0

I am wondering how to access routes in nested resources in rails. I added categories and it as broken my application.

Routes:

resources :categories do  
  resources :posts do
    resources :comments
  end
end 

It errors out in this:

<% @posts.each_with_index do |post, index| %> 
  <%= link_to post do %>  # originally, this used to work but now it says 'undefined method "post_path"'
        <li class="post-title"><%= truncate post.title, length: 50 %></li>
        <li class="post-content"><%= truncate post.content, length: 400 %></li>
        <li><span class="post-comments"><%= post.comments.count %> comments</span></li>
<% end %>

My root is set to posts#index and has a listing of posts. However, the route nesting (originally I didn't have categories) has broken the routes.

Running rake routes I get in part this:

        category_posts GET    /categories/:category_id/posts(.:format)                            posts#index
                       POST   /categories/:category_id/posts(.:format)                            posts#create
     new_category_post GET    /categories/:category_id/posts/new(.:format)                        posts#new
    edit_category_post GET    /categories/:category_id/posts/:id/edit(.:format)                   posts#edit
         category_post GET    /categories/:category_id/posts/:id(.:format)                        posts#show
                       PATCH  /categories/:category_id/posts/:id(.:format)                        posts#update
                       PUT    /categories/:category_id/posts/:id(.:format)                        posts#update
                       DELETE /categories/:category_id/posts/:id(.:format)                        posts#destroy

How can I adjust routes to compensate for nesting? Or is there a better way to nest?

user3162553
  • 2,699
  • 3
  • 37
  • 61

2 Answers2

1

You'd need to define another block that nests posts under category resource:

# Existing
resources :posts do 
  resources :comments
end

# Additional block
resources :categories do  
  resources :posts do
    resources :comments
  end
end

With the additional block, your existing routes remain unchanged so existing routes don't break!

It is always better to restrict the routes to only what you need/use. For example if you only need /categories/:category_id/posts, i.e. just the index method on the posts_controller, then your route will be updated to:

resources :categories do 
  resources :posts, only: [ :index ]
end

This way you have more control on your routes and greater maintainability of the application.

vee
  • 38,255
  • 7
  • 74
  • 78
  • Ok thank you very much. I will not need the categories#index route so I will put: resources :categories, except: [:index] do resources :posts do resources :comments end end – user3162553 Jul 10 '15 at 18:34
0

vee's answer is correct if you want to use the nested routes and still preserve the original URLs. This is recommend this if your site is live and changing the URLs would affect links to your indexed pages.

Otherwise, you should point your links to the nested resource, like this:

<%= link_to post.title, [post.category, post] %>

See: Rails - link_to, routes and nested resources

Community
  • 1
  • 1
Ryenski
  • 9,582
  • 3
  • 43
  • 47
  • Ok, good to know. Still getting my mind wrapped around nested resources. It's my understanding that the Rails docs recommend not nesting more than one level. – user3162553 Jul 10 '15 at 18:44
  • That is true, but it's a convention rather than a constraint. As the [Rails Guides](http://guides.rubyonrails.org/routing.html#nested-resources) says, "deeply-nested resources quickly become cumbersome". Two-level nesting is generally fine, and in this case /categories/:category_id/posts/:post_id actually more meaningful than a flat route structure because you can use /categories/:category_id to display all posts under a category. – Ryenski Jul 10 '15 at 19:01
  • Ok, good to know. I felt like it was the right approach for my application but was worried about straying too far from convention. – user3162553 Jul 10 '15 at 19:30
  • As usual the Rails Guide is a great resource on this: http://edgeguides.rubyonrails.org/routing.html – Ryenski Jul 10 '15 at 19:34