active-record icon indicating copy to clipboard operation
active-record copied to clipboard

[Proposal] for branch 2.1 Refactoring idea for handling relations in Active Record

Open Faryshta opened this issue 9 years ago • 8 comments

I don't know if this will break the Active Record pattern so read carefully. Written in php7 for simplier will be changed to php5 if approved.

interface RelationalRecord
{
    /**
     * Will store the `$query` into an array indexed by the `$name` parameter
     * This will allow creating relations on the fly and later call them with `getRelation()`
     *
     * usage example:
     *
     * ```php
     * $model->setRelation('bigOrders', $model->getOrders()->andWhere(['>=', 'amount', 1000));
     * $model->bigOrders; // calls the query and stores the result on the $model object.
     * ```
     */
    public function setRelation(string $name, ActiveQuery $query = null);

    /**
     * finds the relation named `$name`, executes it and returns it, if no query is already
     * prepared to turn into this relation then will check if a getter is defined for the
     * `$name` property and use that instead.
     *
     * @return static|static[]
     */
    public function getRelation(string $name);

    /**
     * unsets the ActiveRecords associated to the relation so it can be created again.
     */
    public function resetRelation(string $name);

    /**
     * unsets all relations
     */
    public function resetRelations();

    /**
     * If the relation is still an ActiveQuery it can be modified using this method
     *
     * @param callable $callback with the signature `function (ActiveQuery $query){}`
     */
    public function modifyRelation(string $name, callable $callback);
}

With this methods we can modify relations on the fly and simplify how relations are handled right now.

I also think this can be implemented for the 2.0 branch but i think @cebe should confirm it.

Faryshta avatar May 03 '16 03:05 Faryshta

What's the use for dynamic relations?

samdark avatar May 03 '16 11:05 samdark

@samdark for example

$model->setRelation('bigOrders', $model->getOrders()->andWhere(['>=', 'amount', 1000));
$model->bigOrders; // calls the query and stores the result on the $model object.

Its an already existing feature request #6951

Faryshta avatar May 03 '16 15:05 Faryshta

Dynamic relation has no sense to me. Being declared in this way it will not be available for eager loading. While dynamic populating of the relations is already supported:

$model->populateRelation('notDeclaredRelation',  $model->getOrders()->andWhere(['>=', 'amount', 1000)->all());

klimov-paul avatar May 03 '16 16:05 klimov-paul

Being declared in this way it will not be available for eager loading.

I don't see why. I see this as an step to have aliased relations and eager loading.

Faryshta avatar May 03 '16 16:05 Faryshta

I don't see why. I see this as an step to have aliased relations and eager loading.

Eager loading performed at the class scope - not an object. setRelation() method, you propose, can be called only in object scope.

Eager loading:

Order::find()
    ->with(['payment'])
    ->all();

does not operates particular object and thus can not benefir from such methods as setRelation() anyhow.

klimov-paul avatar May 03 '16 17:05 klimov-paul

does not operates particular object and thus can not benefir from such methods as setRelation() anyhow.

Currently. As I said this is a first step, after this we need to figure out a syntax for the eager loading. But it will just be a syntax.

The interface above is to handle relations on the ActiveRecord, another issue would be how to handle relations on the ActiveQuery which is the one doing the eager loadings.

Faryshta avatar May 03 '16 18:05 Faryshta

@Faryshta, dynamic relations are indeed useful. I'm working with these for years (I created my own extensions on top of Yii) now and practice is proving its use every day. However, it requires a deep integration with getters & setters for the reasons mentioned above by Paul.

dynasource avatar Nov 09 '16 15:11 dynasource

In what situations can the use of dynamic relations be better than the static description of relations?

lav45 avatar Jun 19 '19 05:06 lav45

Duplicate of #50

Tigrov avatar Jun 08 '24 11:06 Tigrov