5

Using Yii2 framework I cannot find any built-in functionality to implement something called nested resources in Ruby on Rails (http://guides.rubyonrails.org/routing.html#nested-resources)

For example, an Article has many Comments. So I want that comments related to an article will be accessed via /articles/1/comments URL when index action is used; via /articles/1/comments/create when create action is used and so on...

Do I have to add multiple action-methods to ArticlesController called actionIndexComments(), actionCreateComment()... ?

Or should I pass an ?article_id=1 parameter via GET and use it for filtering in CommentsController ?

Or should I maybe implement custom UrlManager class that can deal with nested routes? (maybe someone has already implemented it?)

What is the best practice for now?

Andrey Pesoshin
  • 1,136
  • 1
  • 14
  • 30

3 Answers3

5

You should be able to do this easily with the UrlManager. It also depends on where you want to put the actual actions. You can put them either in a article controller or comment controller

For example for the comments controller you can define rules like this:

'article/<article_id:\d+>/comments/create/' => 'comment/create',
'article/<article_id:\d+>/comments/' => 'comment/index',

In both cases you can access the article_id (in GET) in the create or index actions. You can do exactly the same thing if you want to put the actions in the article.

Mihai P.
  • 9,307
  • 3
  • 38
  • 49
  • can you please help me, im new in yii, where should i actually define these rules? i have `teams` and `playes` and i want my url to be like `teams/1/player/create` where 1 is `team_id` – nooby Dec 05 '16 at 12:47
4

For more universe:

'GET,HEAD v1/articles/<id:\d+>/comments' =>
    'v1/articles/comment/index',
'GET,HEAD v1/<article/<id:\d+>/comments/<id:\d+>' =>
    'v1/articles/comment/view',
'POST v1/articles/<id:\d+>/comments' =>
    'v1/articles/comment/create',
'PUT,PATCH v1/article/<id:\d+>/comments' =>
    'v1/articles/comment/update',
'DELETE v1/article/<id:\d+>/comments' =>
    'v1/articles/comment/delete',
jamlee
  • 1,234
  • 1
  • 13
  • 26
1

In case it is related to the built-in REST Api and you are using yii\rest\UrlRule instead of yii\web\UrlRule then its $prefix property may help achieving that by doing:

'rules' => [
    [
        'class' => 'yii\rest\UrlRule', 
        'controller' => ['players' => 'v1/player', 'trophies' => 'v1/trophy'],
        'prefix' => 'teams/<team_id:\d+>',
    ],
],

Which will generate the required rules for the following endpoints:

/teams/1/players
/teams/1/players/2
/teams/1/trophies
/teams/1/trophies/4

There is also this extension built on top of that principle and also provides related helper actions.

Salem Ouerdani
  • 7,596
  • 3
  • 40
  • 52
  • Finally solution that works! The missing important trick was: 'controller' => ['players' => 'v1/player', 'trophies' => 'v1/trophy']. – Petr Pánek Jan 20 '21 at 16:34