In rails 2.x I used shallow routes, but this seems to be missing from rails 3 (at least in the API http://apidock.com/rails/ActionController/Resources/resources).
When I pass this option in rails 3 it doesn't throw any errors, but I'm also not getting all of the routes I expected.
Rails 3 routes.rb
resources :users, :shallow=>true do
resources :recipe do
resources :categories do
resources :sections do
resources :details do
end
end
end
end
end
The routes missing that were generated with the rails 2.x equivalent are (just a sample for the recipe resource):
GET new_recipe (I only have new_user_recipe), and
POST recipe (to create a new recipe, I only have POST user_recipe)
It kind of makes sense that these routes wouldn't be generated, but my old code worked around it by passing the user_id in each form (less elegant, agreed).
Question is: Is there documentation for 'shallow' routes in rails 3? Is there a way to generate the routes I'm missing from rails 2.x?
Thanks,
Mike
You need to apply the :shallow option to the nested resources. This should give you what you want:
resources :users do
resources :recipe, :shallow=>true do
resources :categories do
resources :sections do
resources :details do
end
end
end
end
end
If you look at the Rails 3 docs, you'll see that shallow
is an instance method on ActionDispatch::Routing::Mapper::Resources
, just like resource
, resources
, match
, etc. You should be able to nest shallow routes with something like this:
shallow do
resources :users do
resources :recipe do
resources :categories do
resources :sections do
resources :details
end
end
end
end
end
Though it only seems to expand them to 2 levels rather than the full nested route. Check out rake routes
for more.
You can find Rails 3 documentation relating to nested or shallow routes on the Rails Guides site.
While offering advice on how to nest routes, it specifically says that, "Resources should never be nested more than 1 level deep."
It's reasonable that you only have new_user_recipe instead of new_recipe. Why? Because from the recipe's perspective, each and every recipe much belongs to a user.
Another point is that
resources :users, :shallow=>true do
resources :recipe do
resources :categories do
resources :sections do
resources :details do
end
end
end
end
end
is exactly the same as
resources :users do
resources :recipe, :shallow=>true do
resources :categories do
resources :sections do
resources :details do
end
end
end
end
end
:shallow
is inherited as other users pointed out. Think about it, :shallow
means you can omit the left part of the URL pattern once you are sure which exactly resource you are working on. If you put :shallow
on the outer-most layer of your resource, it should have the same effect as you put it on the second layer (recipe in your example). Because you have nothing to omit when you are working on the outer-most resource (users in your example), it's already the left-most part of the URL pattern and it can't be omitted.