yiisoft / active-record

Active Record database abstraction layer
https://www.yiiframework.com/
BSD 3-Clause "New" or "Revised" License
69 stars 29 forks source link

Suggestion to add multi-level relations to ActiveRecord::extraFields() #15

Open alexweb-zz opened 10 years ago

alexweb-zz commented 10 years ago

Currrently there is no possibility to dynamically manage relations that should be included to respond in case when relation level is bigger than one. For example we have model Business and you can define Locations relation like this:

    public function extraFields()
    {
        $fields = parent::fields();
        $fields[]='locations';
        return $fields;
    }

And then you can include it to respond using ?expand="locations"

But if we want to include Locations together with related location Schedules, then that doesn't work.

I suggest to implement multi-level relations (using dot notation):

    public function extraFields()
    {
        $fields = parent::fields();
        $fields[]='locations';
        $fields[]='locations.schedule';
        return $fields;
    }

And then it will be possible to use it this way: ?expand="locations, locations.schedule"

I think it would be nice, because it's very often needed to manage relation records that should be included to respond. Is it possible?

qiangxue commented 10 years ago

I thought about this. It's not trivial, especially if you also want to support selectively pick up certain fields from relations.

cebe commented 10 years ago

can't we delegate this to the extraFields method of the related model and use definitions from there?

qiangxue commented 10 years ago

How will the GET query parameter looks like? How to go from there to the method parameters?

creocoder commented 10 years ago

can't we delegate this to the extraFields method of the related model and use definitions from there?

We do not need do that!

Please read this: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#autoloading

All we need is support expand or embed parameter.

I thought about this. It's not trivial, especially if you also want to support selectively pick up certain fields from relations.

From client side there is no feature to selectively pick up certain fields from relations in expand/embed. It will be overcoding.

From model side it can be easily handled like:

class Product extends ActiveRecord
{
    public function extraFields()
    {
        return [
            'price',
            'quantity',
            'categories' => ['id', 'title'], <- LOOK HERE
        ];
    }
}
creocoder commented 10 years ago

So query like GET /products?expand=price,categories will give you result:

{
    "id": 1,
    "title": "Foo",
    "price": "$10",
    "categories": [
        {
            "id": 1,
            "title": "Bar"
        },
        {
            "id": 2,
            "title": "Baz"
        }
    }
}
xterr commented 9 years ago

+1

bogdaniy commented 9 years ago

+1

jcvalerio commented 9 years ago

+1

eberon commented 9 years ago

+1

akaNightmare commented 9 years ago

+1

kadanin commented 9 years ago

+1

juanagu commented 9 years ago

+1

kadanin commented 9 years ago

Where in code YII2 looks for "expand" parameter to choose which extra fields must be shown?

cebe commented 9 years ago

Where in code YII2 looks for "expand" parameter to choose which extra fields must be shown?

https://github.com/yiisoft/yii2/blob/master/framework/rest/Serializer.php#L159

riyaskp commented 9 years ago

+1

One-art commented 9 years ago

This problem make me cry, really! I want to get list of "items" with author. And in author I want to get Full name extra field. But it's not working at all. Expand not using custom fields.

jasonhancock commented 9 years ago

+1

ebuzzz commented 9 years ago

For the moment, I've worked around this problem by overruling the fields() call in my ActiveRecord model.

class MultiLevelActiveRecord extends \yii\db\ActiveRecord
{
    public function fields()
    {
        $fields = parent::fields();

        // Add multi-level expanded fields
        $expandFields = explode(',', Yii::$app->request->getQueryParam('expand'));
        foreach ($expandFields as $field)
        {
            if (strpos($field, strtolower($this->formName()).'.') === 0)
            {
                $fields[] = substr($field, strlen($this->formName()) + 1);
            }
        }

        return $fields;
    }
}

That enabled me to use:

?expand=category,author.name

But only based on exact modal names, and not based on relations. It's dirty, but does the job for me.

mushahidh commented 9 years ago

+1

supr-d commented 9 years ago

+1

tendallas commented 9 years ago

+1

jacksumit commented 9 years ago

+1

pgarriga commented 8 years ago

+1

manquer commented 8 years ago

+1

Tr9 commented 8 years ago

+1

Forin commented 8 years ago

+1

archlemon commented 8 years ago

+1

Faryshta commented 8 years ago

+1

pedromalta commented 8 years ago

+1

nancoder commented 8 years ago

+1

alex-nesterov commented 8 years ago

http://domain/restapi/users/1/posts/123 (#3319) +1

dawei101 commented 8 years ago

+1

nkostadinov commented 8 years ago

I'm currently implementing something to handle this issue. I use scopes, so I define each scope in the model and the client requests the scopes to be returned. The request is

?scope=profile,orders,locations 

and in the model I define them as arrays like in fields(). I personally don't think that the client should be able to define exactly what to be returned it should be limited to scopes defined on the server. It can be easily used with oauth server(in my case) which limits the visible scopes for each client.

nerburish commented 8 years ago

+1

xfg commented 8 years ago

+1

vadim-bulochnik commented 8 years ago

+1

ilves commented 8 years ago

+1

panrus commented 8 years ago

+1

vertamedia-teamcity-github commented 8 years ago

+1

sazo commented 8 years ago

+1

vnddr commented 8 years ago

+1

tdimdimich commented 8 years ago

+1

dcb9 commented 8 years ago

+1

SilverFire commented 8 years ago

Please, use :+1: emoticon to the first message in this issue instead of adding more "+1" comments. Thank you!

Faryshta commented 8 years ago

@SilverFire i think the reason is because reactions emojis doesn't get attention.

SilverFire commented 8 years ago

We have enough members asking for this feature, so we already know that we should take care about this issue. Clicking "+1" is OK to let us know, that you want this kind of enhancement too. We appreciate all kinds of help. We are thankful for showing, what is important for you and will take care of it. GitHub added emotions to help managing daily flow of changes in repo. Thank you

SilverFire commented 8 years ago

I'm not locking the conversation. We will be happy to hear more feedback from you

Faryshta commented 8 years ago

There are currently two PR's from @mdmunir with two different approaches on how to solve this feature request #11493 and #11476 I think the people here should check them and see which oneis easier to implement and use.

gonimar commented 7 years ago

+1

lubobill1990 commented 7 years ago

+1