Rails routes with scope: "locale" and shallow nested resources

So, I want Rails to handle the routes specific to me, for example,

/en/companies /nl/companies 

This works great with route determination:

 scope "(:locale)", :locale => /en|nl/ do resources :companies end 

But at the same time, companies have small invested resources, for example:

 scope "(:locale)", :locale => /en|nl/ do resources :companies, :shallow => true do resources :pages end end 

This allows you to use paths like /en/companies/1/pages , but not paths like /en/pages/1/edit . Since the "shallow" part also shares the "local" part of the path, it seems like I'm stuck with /pages/1/edit?locale=en . Is there a way to get Rails to handle small nested resources with locales in such a way that I can use /en/pages/1/edit ?

+8
ruby-on-rails ruby-on-rails-3 internationalization routing
source share
2 answers

Oh yes! I found the answer in the API documentation . The magic is in the key :shallow_path , and in the example above it works like this:

 scope :path => "(:locale)", :shallow_path => "(:locale)", :locale => /en|nl/ do resources :companies, :shallow => true do resources :pages end end 

Now a URL like /en/pages/1/edit works fine!

+14
source share

Thank you very much Pascal, it was really useful for me. I noticed a similar behavior when setting up my nested resources.

I would add something, an option to use the block operator for small instead of parameter. Right now, using the syntax you specified, only direct descendants (: pages) will be shallow.

If you want to nest one level deeper (let it skip the argument about whether these are best practices or not), using a shallow block will be as insignificant as necessary:

 resources :users do shallow do resources :categories do resources :sections do resources :pages end end resources :news end end 

Here is an example of what available route helpers you will have for all resources nested inside: users

 new_category_section GET (/:locale)(/:locale)/categorys/:category_id/sections/new(.:format) {:locale=>/fr|en/, :action=>"new", :controller=>"sections"} edit_section GET (/:locale)(/:locale)/sections/:id/edit(.:format) {:locale=>/fr|en/, :action=>"edit", :controller=>"sections"} section GET (/:locale)(/:locale)/sections/:id(.:format) {:locale=>/fr|en/, :action=>"show", :controller=>"sections"} PUT (/:locale)(/:locale)/sections/:id(.:format) {:locale=>/fr|en/, :action=>"update", :controller=>"sections"} DELETE (/:locale)(/:locale)/sections/:id(.:format) {:locale=>/fr|en/, :action=>"destroy", :controller=>"sections"} section_pages GET (/:locale)(/:locale)/sections/:section_id/pages(.:format) {:locale=>/fr|en/, :action=>"index", :controller=>"pages"} POST (/:locale)(/:locale)/sections/:section_id/pages(.:format) {:locale=>/fr|en/, :action=>"create", :controller=>"pages"} new_section_info_page GET (/:locale)(/:locale)/sections/:section_id/pages/new(.:format) {:locale=>/fr|en/, :action=>"new", :controller=>"pages"} dit_info_page GET (/:locale)(/:locale)/pages/:id/edit(.:format) {:locale=>/fr|en/, :action=>"edit", :controller=>"pages"} info_page GET (/:locale)(/:locale)/pages/:id(.:format) {:locale=>/fr|en/, :action=>"show", :controller=>"pages"} PUT (/:locale)(/:locale)/pages/:id(.:format) {:locale=>/fr|en/, :action=>"update", :controller=>"pages"} DELETE (/:locale)(/:locale)/pages/:id(.:format) {:locale=>/fr|en/, :action=>"destroy", :controller=>"pages"} 
+3
source share

All Articles