This project is archived and is in readonly mode.
Routing conflicts with shallow routes
Reported by Jose Prado | September 9th, 2009 @ 07:56 AM
I'm quite new to Rails (less than a week in) and I've run into a snag.
I have three models. User has many Groups through Memberships. Group has many Users through Memberships. Membership belongs to Users and Groups.
Everything was working fine until I tried to use the shallow
routes option. I've set up RESTful routing using:
map.resources :users, :has_many => :groups, :shallow => true
map.resources :groups, :has_many => :users, :shallow => true
The User routes work fine but now the Group routes are broken
since I can't access /groups/new anymore. A call of "rake routes"
clearly shows the problem (I took out the non-GET routes for
simplicity and added text because the Lighthouse syntax parser
butchers lines with space at the beginning.):
user_groups GET /users/:user_id/groups(.:format) {:controller=>"groups", :action=>"index"}
new_user_group GET /users/:user_id/groups/new(.:format) {:controller=>"groups", :action=>"new"}
edit_group GET /groups/:id/edit(.:format) {:controller=>"groups", :action=>"edit"}
group GET /groups/:id(.:format) {:controller=>"groups", :action=>"show"}
users GET /users(.:format) {:controller=>"users", :action=>"index"}
new_user GET /users/new(.:format) {:controller=>"users", :action=>"new"}
edit_user GET /users/:id/edit(.:format) {:controller=>"users", :action=>"edit"}
user GET /users/:id(.:format) {:controller=>"users", :action=>"show"}
group_users GET /groups/:group_id/users(.:format) {:controller=>"users", :action=>"index"}
new_group_user GET /groups/:group_id/users/new(.:format) {:controller=>"users", :action=>"new"}
new_group_user GET /users/:id/edit(.:format) {:controller=>"users", :action=>"edit"}
new_group_user GET /users/:id(.:format) {:controller=>"users", :action=>"show"}
groups GET /groups(.:format) {:controller=>"groups", :action=>"index"}
new_group GET /groups/new(.:format) {:controller=>"groups", :action=>"new"}
new_group GET /groups/:id/edit(.:format) {:controller=>"groups", :action=>"edit"}
new_group GET /groups/:id(.:format) {:controller=>"groups", :action=>"show"}
The route "group GET /groups/:id(.:format) {:controller=>"groups", :action=>"show"}" takes precedence over the "new_group GET /groups/new(.:format) {:controller=>"groups", :action=>"new"}" route so it seems that "new" is interpreted as the :id parameter.
If I remove the shallow routes option and run "rake routes"
again, we get similar routing, but in this case, the /groups/new
path works as expected. Here's the relevant sections from these
routes:
user_groups GET /users/:user_id/groups(.:format) {:controller=>"groups", :action=>"index"}
new_user_group GET /users/:user_id/groups/new(.:format) {:controller=>"groups", :action=>"new"}
edit_user_group GET /users/:user_id/groups/:id/edit(.:format) {:controller=>"groups", :action=>"edit"}
user_group GET /users/:user_id/groups/:id(.:format) {:controller=>"groups", :action=>"show"}
groups GET /groups(.:format) {:controller=>"groups", :action=>"index"}
new_group GET /groups/new(.:format) {:controller=>"groups", :action=>"new"}
edit_group GET /groups/:id/edit(.:format) {:controller=>"groups", :action=>"edit"}
group GET /groups/:id(.:format) {:controller=>"groups", :action=>"show"}
Looking at these routes, it seems that when the nested routes get shortened with the shallow routes option, they end up becoming higher precedence routes which kill the natural Group routes. More specifically, route "user_group GET /users/:user_id/groups/:id(.:format) {:controller=>"groups", :action=>"show"}" becomes route "group GET /groups/:id(.:format) {:controller=>"groups", :action=>"show"}" which is causing the conflict.
So again, Rails beginner here so I'm not sure if this is how it's supposed to work, but it doesn't seem like expected behavior to me. Any tips/thoughts?
Comments and changes to this ticket
-
Pete Campbell November 6th, 2009 @ 11:21 PM
This doesn't seem to me to be a bug, routes are executed in order and I think your analysis is correct. One solution is to only generate the nested resources for :users, eg.
map.resources :users do |users|
users.resources :groups, :shallow => true, :only => [:index, :new] endThis will generate only the /users/:user_id/groups and /users/:user_id/groups/new routes, so all /groups routes will fall through to the map.resources :groups, :shallow => true routes
-
Mike Riley July 29th, 2010 @ 03:37 PM
- State changed from new to invalid
- Importance changed from to
Hello,
I am going to mark this as invalid based on Pete's reply. If you are still having issues with configuring and setting up your routes, you could also ask at http://www.railsforum.com/ or http://www.ruby-forum.com/forum/3 for further help. I have had good luck with those sites.
Mike Riley
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>