Is it correct for a path helper to pass a nested resource id as the id of the resource it is nested in?

To bring some context to the question - I have two models: Subject and Post. Since each subject can contain many posts, I decided to create a nested route.

resources :subjects, path: 'threads', only: [:index, :show] do
    resources :posts
  end

That of course led to the creation of subject_post_path helper, which I decided to use in my view.

<% @subject.posts.each do |post| %>
    <%= link_to subject_post_path(post) do %>
        <h3><%= post.title %></h3>
    <% end %>
<% end %>

Based on experience with subject_path, which created links in threads/:id fashion, I expected I would get a link like threads/1/posts/2, instead I got links such as those:

<a href="/threads/2/posts/1"></a>
<a href="/threads/3/posts/1"></a>
<a href="/threads/4/posts/2"></a>

I figured the first parameter is the id of the post and the second was the id of the subject, but my confusion grew further when I checked one of the logs:

Started GET "/threads/3/posts/1" for 127.0.0.1 at 2023-10-07 19:51:55 +0200
Processing by PostsController#show as HTML
  Parameters: {"subject_id"=>"3", "id"=>"1"}

So it appears that id pointing to a post is passed as a subject id and vice versa. That makes me want to ask - is that a default behaviour for a path helper created in a nested route? If not, what could be the reason behind this behaviour?

The guide Rails Routing from the Outside In — Ruby on Rails Guides doesn’t quite spell it out, but for nested resources you need to specify all of them - try subject_post_path(@subject, post).

2 Likes

Thanks a lot, it helped!

hello there, Thankyou for sharing this solution.