Cu1ture
Cu1ture

Reputation: 1283

What are nested routes for in Rails?

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?

Upvotes: 4

Views: 5362

Answers (2)

Mandeep
Mandeep

Reputation: 9173

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

Upvotes: 5

August
August

Reputation: 12558

Correct, having the article in the path is redundant when dealing with a preexisting comment (because you can get the article from the comment). To avoid this, you can use shallow routes:

#routes.rb

resources :articles, shallow: true do
  resources :comments
end

# or use a `shallow` block
shallow do
  resources :articles
    resources :comments
  end
end

Upvotes: 2

Related Questions