3.7 Nested Resources
What you’re aiming for here is a URL that looks like:
/auctions/3/bids/5
To created nested resource routes, put this in routes.rb
:
resources :auctions do
resources :bids
end
3.7.1 RESTful Controller Mappings
For the above example in routes.rb
, there are two controllers that come into play, the AuctionsController
and the BidsController
3.7.2 Considerations
Is nesting worth it? For single routes, a nested route usually doesn’t tell you anything you wouldn’t be able to figure out anyway. After all, a bid belongs to an auction.
That means you can access bid.auction_id just as easily as you can params[:auction_id], assuming you have a bid object already.
A common rationale for judicious use of nested resources, and the one most often issued by David, is the ease with which you can enforce permissions and context-based constraints. Typically, a nested resource should only be accessible in the context of its parent resource, and it’s really easy to enforce that in your code based on the way that you load the nested resource using the parent’s Active Record association.
3.7.3 Deep Nesting?
Resources should never be nested more than one level deep.
The Rails 4 Way
That advice is based on experience and concerns about practicality. The helper methods for routes nestedmore than two levels deep become long and unwieldy. It’s easy to make mistakes with them and hard tofigure out what’s wrong when they don’t work as expected.
Assume that in our application example, bids have multiple comments. We could nest comments under bids in the routing like this:
resources :auctions do
resources :bids do
resources :comments
end
end
Instead, the following is suggested:
resources :auctions do
resources :bids
end
resources :bids do
resources :comments
end
resources:comments
Notice that each resource (except auctions) is defined twice, once in the top-level namespace, and one in its context. The rationale? When it comes to parent-child scope, you really only need two levels to work with. The resulting URLs are shorter and the helper methods are easier to work with.
3.7.4 Shallow Routes
As of Rails 2.3, resource routes accept a :shallow option that helps to shorten URLs where possible. The goal is to leave off parent collection URL segments where they are not needed. The end result is that the only nested routes generated are for the :index
, :create
, and :new
actions. The rest are kept in their own shallow URL context.
It’s easier to illustrate than to explain, so let’s define a nested set of resources and set :shallow
to true
:
resources :auctions, shallow: true do
resources :bids do
resources :comments
end
end
alternatively coded as follows (if you’re block-happy)
resources :auctions do
shallow do
resources :bids do
resources :comments
end
end
end
If you analyze the routes generated carefully, you’ll notice that the nested parts of the URL are only included when they are needed to determine what data to display.
网友评论