Reputation: 1429
I'd love to know how Rails infers the parent of a nested resource automatically. I have done some homework down in RouteSet but in all that module_eval and dynamically generated methods I haven't figured out how it infers the parent.
Assume the evergreen Posts and Comments data hierarchy with the appropriate models and controllers.
A nested routing of these would looks like this
resources :posts do
resources :comments
end
When I am in the context of the controller or views of the comments rails is able to infer the post like so:
post_comments_path
Which would map to the comments index under the current Post.
When I am in the context of the posts controller and views I rails can no longer infer the post for this route, requiring me to supply it.
post_comments_path # error
post_comments_path(@post) # ok
It has been suggested in other threads that the second row is the correct way to go.
I may be crazy, but I'd love to find out how Rails is able to infer the Post. I have an edge case where one or two actions are on the root controller for a menu listing routes to mostly nested stuff. I would prefer to tell Rails what the current parent is for these few actions rather than clutter my view code with explicit parent references all over the place.
Update:
I did try the basic thing of setting a post_id parameter. Verifying that it is indeed set on both request-params and params without success. I have vague memories of Rails making copies of the params so perhaps the routing helpers have a separate copy without my added parameter? (Setting a @post instance variable has no effect either. I just had to check.)
Upvotes: 2
Views: 734
Reputation: 29308
Okay so it seems to have to do with the defaults parameter of a path.
ie.
get '/posts/:post_id/comments', to: "comments#index", as: :show_default_comments, defaults:{post_id: Post.all.first.id}
this will show you the comments index
action based on the very first post so I think that when you are in the comments controller the defaults post_id
is set to the current value of post_id
. I would have to do more testing to confirm this.
(Copied from my comment) Found it. default_url_options Here. Confirmed that doing this does work although it broke my index view but this is as far as I am going seems default_url_options gets passed in at some point and this is where the inference occurs and you can set it using the method in the link.
defining a url_options method in the controller to set the default_url_options for a path will allow you to specify a parent dynamically for routing purposes.
Upvotes: 1