Reputation: 2031
I want to configure my Rails routing such that these cases work:
/username #=> { :controller => "houses",
# :action => "index",
# :user_id => "username" }
/username/housename #=> { :controller => "houses",
# :action => "show",
# :user_id => "username",
# :id => "housename" }
/username/edit #=> { :controller => "users",
# :action => "edit",
# :id => "username" }
In other words, I want /:user_id
to be a regular user resource, and have a nested resource for it, which is mounted directly on the root. So, I want /username/housename
instead of /username/houses/housename
. I tried using :path => "/"
for the nested resources, but this somehow clashes with other actions such as `:edit. I'm lost - can this be done?
Upvotes: 3
Views: 438
Reputation: 27374
What you are trying to do will create conflicts, which is why Rails is not letting you do it.
Consider the situation where some user bob has a house named "edit". In this case, where is Rails supposed to route '/bob/edit' to? There are two possibilities:
{ :controller => "houses", :action => "show", :user_id => "bob", :id => "edit" }
and:
{ :controller => "users", :action => "edit", :id => "bob" }
So to answer your question, as is what you are trying to do cannot be done until you remove the ambiguity.
UPDATE:
Borrowing from @sevenseacat's answer, I think this should do what you want, in the case of a route /bob/edit prioritizing the edit action for user "bob" over the show action for a house named "edit":
resources :users, path: '/', only: :edit
resources :users, path: '/', only: :show do
resources :houses, only: :show, path: ''
end
I get these routes:
edit_user GET /:id/edit(.:format) users#edit
user_house GET /:user_id/:id(.:format) houses#show
user GET /:id(.:format) users#show
Notice that the edit_user
path appears above the user_house
path, which guarantees that it will get priority when there is a conflict.
Upvotes: 2
Reputation: 25029
Something like this may be what you're after:
resources :users, path: '/', only: [:show, :edit] do
resources :houses, only: [:show], path: ''
end
rake routes
tells me:
user_house GET /:user_id/:id(.:format) houses#show
edit_user GET /:id/edit(.:format) users#edit
GET /:id(.:format) users#show
Upvotes: 1