Rails allows you to define routes with named prefixes. I expected Rails to somehow know that I wanted my prefix to separate the rest of the name with an underscore.

Here was my original routes:

config/routes.rb
 1 ActionController::Routing::Routes.draw do |map|
 2   map.resources :parties, :path_prefix => "/admin" do |parties|
 3     parties.resources :addresses,
 4         :controller => "address_contact_routes",
 5         :name_prefix => :party
 6   end
 7 
 8   map.resources :addresses,
 9       :controller => "address_contact_routes"
10 end

Then, when I tried to use my route, I was getting a NoMethodError:

 1   1) Error:
 2 test_can_show(AddressContactRoutesControllerTest::PartyWithAddressTest):
 3 ActionView::TemplateError: undefined method `party_address_path' for #<#<Class:0xb768f6ac>:0xb63ee41c>
 4     On line #3 of app/views/address_contact_routes/_address_contact_route.rhtml
 5 
 6     1: <%
 7     2:   if address_contact_route.routable && !address_contact_route.new_record? then
 8     3:     update_url = "#{party_address_path(address_contact_route.routable, address_contact_route)}.txt"
 9     4:   end
10     5: -%>
11     6: <% inline_fields_for(:address, address_contact_route, :url => update_url) do |f| -%>
12 
13     #{RAILS_ROOT}/app/views/address_contact_routes/_address_contact_route.rhtml:3:in `_run_rhtml_47app47views47address_contact_routes47_address_contact_route46rhtml'

After a bit of sleuthing (and adding messages to ActionController::Routing::RouteSet#add_named_route), I found out that I was supposed to put the underscore myself on the prefix, like this:

1 map.resources :parties, :path_prefix => "/admin" do |parties|
2   parties.resources :addresses,
3       :controller => "address_contact_routes",
4       :name_prefix => :party_
5 end

It was also interesting to see all those generated routes. I discovered that the route with a format was named formatted_whatever.

Here’s a diff against the 1.2 branch of Rails that allows you to see all the generated routes as they are read:

 1 $ svn diff vendor/rails/actionpack/lib/action_controller
 2 Index: vendor/rails/actionpack/lib/action_controller/routing.rb
 3 ===================================================================
 4 --- vendor/rails/actionpack/lib/action_controller/routing.rb    (revision 6424)
 5 +++ vendor/rails/actionpack/lib/action_controller/routing.rb    (working copy)
 6 @@ -349,7 +349,9 @@
 7 
 8          method_decl = "def generate_extras(#{args})\npath, hash = generate_raw(options, hash, expire_on)\n[path, extra_keys(options)]\nend"
 9          instance_eval method_decl, "generated code (#{__FILE__}:#{__LINE__})"
10 -        raw_method
11 +        returning raw_method do
12 +          RAILS_DEFAULT_LOGGER.debug {raw_method}
13 +        end
14        end
15 
16        # Build several lines of code that extract values from the options hash. If any
17 @@ -999,6 +1001,7 @@
18          deprecate :root => "(as the the label for a named route) will become a shortcut for map.connect '', so find another name"
19 
20          def method_missing(route_name, *args, &proc)
21 +          RAILS_DEFAULT_LOGGER.debug {"ActionController::Routing::RouteSet::Mapper#method_missing(#{route_name.inspect}, #{args.inspect})"}
22            super unless args.length >= 1 && proc.nil?
23            @set.add_named_route(route_name, *args)
24          end
25 @@ -1175,6 +1178,7 @@
26        end
27 
28        def add_named_route(name, path, options = {})
29 +        RAILS_DEFAULT_LOGGER.debug {"ActionController::Routing::RouteSet#add_named_route(#{name.inspect}, #{path.inspect}, #{options.inspect})"}
30          named_routes[name] = add_route(path, options)
31        end
32 

For reference, here are all the generated routes for this declaration:

config/routes.rb
1 ActionController::Routing::Routes.draw do |map|
2   map.resources :layouts, :path_prefix => "/admin"
3 end

layouts => "/admin/layouts"
formatted_layouts => "/admin/layouts.:format"
new_layout => "/admin/layouts/new"
formatted_new_layout => "/admin/layouts/new.:format"
edit_layout => "/admin/layouts/:id;edit"
formatted_edit_layout => "/admin/layouts/:id.:format;edit"
layout => "/admin/layouts/:id"
formatted_layout => "/admin/layouts/:id.:format"

EDIT (2007-03-14 16:52 EDT): Changed link to routing.rb file to the Rails Trac Browser.

Search

Your Host

A picture of me

I am François Beausoleil, a Ruby on Rails and Scala developer. During the day, I work on Seevibes, a platform to measure social interactions related to TV shows. At night, I am interested many things. Read my biography.

Top Tags

Books I read and recommend

Links

Projects I work on

Projects I worked on