I have those two resources which share the same controller. So far, my approach was routing with an special type parameter:
resources :bazs do
resources :foos, controller: :foos, type: :Foo
resources :bars, controller: :foos, type: :Bar
end
The routes work as expected, but all my links are like this:
/bazs/1/foos/new?type=Foo
/bazs/1/bars/new?type=Bar
instead of
/bazs/1/foos/new
/bazs/1/bars/new
How do I pass parameters to the controller without messing the links?
Try something like this:
resources :bazs do
get ':type/new', to: 'foos#new'
end
For the verbs in which you need 2 IDs,
resources :bazs do
get ':type/:id', to: 'foos#show', on: :member
end
Then you have both params[:bazs_id] and params[:id].
You can also do:
resources :bazs do
member do
get ':type/new', to: 'foos#new'
get ':type/:id', to: 'foos#show'
end
end
in order to always have params[:bazs_id].
For the root level conflicts you mentioned, you can do something like:
constraints(type: /foos|bars/) do
get ':type/new', to: 'foos#new'
get ':type/:id', to: 'foos#show'
end
In your routes, type:
is setting a parameter type
which is appended on the URI. Another option could be, for each route, to define defaults
, which would be parameters only be accessible by the controller and not appear in the URI.
The documentation on defaults explains this pretty well.
Example:
resources :bazs do
resources :foos, controller: :foos
resources :bars, controller: :foos
end