views:

13

answers:

2

I'm having trouble getting url_for to render take to_param into account when choosing which route to use.

I have two sets of routes that use the same model (Foo). If Foo.is_special, the url should map to /special/:action. If it isn't, it should map to /:id/:action. Because it's the same model, I'd like url_for to automatically know which path to map to, depending on is_special.

routes.rb:

map.special 'special/:action', :controller => 'bar', :id => 'special'
map.regular ':id/:action', :controller => 'bar', :id => /\d+/

foo.rb:

def to_param
   is_special ? 'special' : id.to_s
end

This works when I set :id explicitly. For example:

url_for(:controller => 'bar', :id => 'special')
url_for(:controller => 'bar', :id => @foo)

Generates the correct url for special when :id is set explicitly to 'special', and when @foo is_special == false. However, when @foo.is_special == true, the special route isn't recognized.

A: 

Yes, to_param will be called to translate @foo into a string. Are you sure that it isn't being called? Maybe the problem is somewhere else. Try it in the console to make sure. To test routes in the console you can first enter

include ActionController::UrlWriter; default_url_options[:host] = 'localhost:3000'

Max Williams
A: 

Not sure if this is the expected behavior, but this works:

map.special ':id/:action', :controller => 'bar', :id => 'special'

Instead of

map.special 'special/:action', :controller => 'bar', :id => 'special'
phillee