I am new to learning Rails and have just encountered nested routes. The example I am looking at involves blog articles and comments. I am trying to undestand what the benefit of nested routes are in Rails.
As far as I can tell all the information contained in a nested route for a comment such as /articles/:article_id/comments/:id(.:format)
is all contained in the comment object itself so it does not communicating additional information to the Action.
Why not just have unnested routes such as /comments/:id(.:format)
?
There is obviously a very good reason for using nested routes but I havent been able to work it out. The only benefit I can see so far is it gives a better illustration of the relation between articles and comments when reading the URL but all this information is contained in the comment object anyway.
Could someone explain this?
In your model you would have setup this association
class Article< ActiveRecord::Base
has_many :comments
end
class Comment< ActiveRecord::Base
belongs_to :article
end
So each comment is associated with an article and you need some logic to find corresponding article for a comment
This is where nested route comes in and lets you find article for that comment in your controller action. If you look at that route again
/articles/:article_id/comments/:id(.:format)
This is the comment controllers show action and this route allows you to find both article and your comment inside show action
def show
@article = Article.find(params[:article_id])
@comment = Comment.find(params[:id])
# if you are not using nested routes then you can find out associated article by
@article = @comment.article # but you'll have to query your database to get it which you can simply find if you are using nested route
end
More than the show action(where you can use some other logic to find article associated with that comment) you need nested route for your new action where you have to find that article and then build a comment for that article by something like
def new
@article = Article.new
@comment = @article.comments.build
end
As @August
pointed out you can separate out actions for which you want your route to be nested by using shallow nesting, you can do:
resources :articles do
resources :comments, shallow: true
end
Checkout nested routes
for more information