Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

namespaced controllers routing - params and url_for

#5052

routes.rb:

namespace :admin do
  root :to => 'index#index'
  match ":controller(/:action(/:id))"
end
root :to => "site/games#index"
namespace :site do
  root :to => redirect('/')
  match ":controller(/:action(/:id))"
end

When I type in direct URL into the browser, all works fine, like:
localhost:3000/admin/ -> admin/index#index
localhost:3000/admin/reports -> admin/reports#index
localhost:3000/site/ -> site/games#index
localhost:3000/site/security/login -> site/security#login

but when I look in the params, it's not that good:

--- !map:ActiveSupport::HashWithIndifferentAccess 
action: index
controller: reports

(controller should be admin/reports)

Now, because of that - url_for doesn't work as expected:

url_for :controller => 'admin/index', :action => 'index' WORKS FINE
url_for :controller => 'admin/reports', :action => 'index' DOESN'T WORK: No route matches {:controller=>"admin/reports"}
url_for :controller => 'site/security', :action => 'login' DOESN'T WORK: No route matches {:controller=>"site/security", :action=>"login"}

url_for :controller => 'reports', :action => 'index' DOES WORK, but it sends to admin/reports even if called in site/security/login

etc.

If I swap the namespaces declarations, it's all working fine inside "site/" but does not inside "admin/".

Reported by Nataniel · July 6th, 2010 @ 11:16 AM

State: resolved
Milestone: none
Assigned to: José Valim José Valim
Importance: Low

Activity

  1. Nataniel
    Nataniel

    I'm working with edge.

    July 6th, 2010 @ 11:17 AM

  2. Repository
    Repository
    • State changed from new to resolved

    (from [b802a0d4c72fbd605b92e9f403c9b8765a6e480c]) When a dynamic :controller segment is present in the path add a Regexp constraint that allow matching on multiple path segments.

    Using a namespace block isn't compatible with dynamic routes so we
    raise an ArgumentError if we detect a :module present in the scope.

    [#5052 namespaced controllers routing - params and url_for state:resolved]

    Signed-off-by: José Valim jose.valim@gmail.com
    http://github.com/rails/rails/commit/b802a0d4c72fbd605b92e9f403c9b8...

    July 6th, 2010 @ 11:16 PM

  3. Nataniel
    Nataniel
    • Assigned user set to José Valim

    Now, following entry in routes.rb is forbidden:

    namespace :admin do
       match ":controller(/:action(/:id))", :id => /\d+/
    end
    

    So is there any way to use modules with defaults routes? In my app I have few modules, like admin/, site/, api/ and I don't want to mix the controllers together - do I have to declare each controller in routes.rb to achieve it?

    July 7th, 2010 @ 12:49 PM

  4. José Valim
    José Valim
    • Importance changed from to Low

    Nataniel,

    You should just invoke call without namespace:

    match ":controller(/:action(/:id))", :id => /\d+/
    

    However, if you want to allow just admin controllers, you can dan do something like this:

    match ":controller(/:action(/:id))", :id => /\d+/, :controller => /admin\/.+?/
    

    July 7th, 2010 @ 12:53 PM

  5. Nataniel
    Nataniel

    Thanks a lot, it's all clear and working great now!

    July 7th, 2010 @ 01:19 PM