Named resources with name prefixes
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:1 2 3 4 5 6 7 8 9 10 |
ActionController::Routing::Routes.draw do |map| map.resources :parties, :path_prefix => "/admin" do |parties| parties.resources :addresses, :controller => "address_contact_routes", :name_prefix => :party end map.resources :addresses, :controller => "address_contact_routes" end |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
1) Error:
test_can_show(AddressContactRoutesControllerTest::PartyWithAddressTest):
ActionView::TemplateError: undefined method `party_address_path' for #<#<Class:0xb768f6ac>:0xb63ee41c>
On line #3 of app/views/address_contact_routes/_address_contact_route.rhtml
1: <%
2: if address_contact_route.routable && !address_contact_route.new_record? then
3: update_url = "#{party_address_path(address_contact_route.routable, address_contact_route)}.txt"
4: end
5: -%>
6: <% inline_fields_for(:address, address_contact_route, :url => update_url) do |f| -%>
#{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 2 3 4 5 |
map.resources :parties, :path_prefix => "/admin" do |parties| parties.resources :addresses, :controller => "address_contact_routes", :name_prefix => :party_ end |
It was also interesting to see all those generated routes. I discovered that the route with a format was named formatted_whatever.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
$ svn diff vendor/rails/actionpack/lib/action_controller
Index: vendor/rails/actionpack/lib/action_controller/routing.rb
===================================================================
--- vendor/rails/actionpack/lib/action_controller/routing.rb (revision 6424)
+++ vendor/rails/actionpack/lib/action_controller/routing.rb (working copy)
@@ -349,7 +349,9 @@
method_decl = "def generate_extras(#{args})\npath, hash = generate_raw(options, hash, expire_on)\n[path, extra_keys(options)]\nend"
instance_eval method_decl, "generated code (#{__FILE__}:#{__LINE__})"
- raw_method
+ returning raw_method do
+ RAILS_DEFAULT_LOGGER.debug {raw_method}
+ end
end
# Build several lines of code that extract values from the options hash. If any
@@ -999,6 +1001,7 @@
deprecate :root => "(as the the label for a named route) will become a shortcut for map.connect '', so find another name"
def method_missing(route_name, *args, &proc)
+ RAILS_DEFAULT_LOGGER.debug {"ActionController::Routing::RouteSet::Mapper#method_missing(#{route_name.inspect}, #{args.inspect})"}
super unless args.length >= 1 && proc.nil?
@set.add_named_route(route_name, *args)
end
@@ -1175,6 +1178,7 @@
end
def add_named_route(name, path, options = {})
+ RAILS_DEFAULT_LOGGER.debug {"ActionController::Routing::RouteSet#add_named_route(#{name.inspect}, #{path.inspect}, #{options.inspect})"}
named_routes[name] = add_route(path, options)
end |
1 2 3 |
ActionController::Routing::Routes.draw do |map| map.resources :layouts, :path_prefix => "/admin" 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.