Unexpected routes behavior

I must be doing something wrong in my routing.

In my routes I have…

map.with_options :controller => ‘users’, :action => ‘revisions’ do |
user|
user.remedy_revisions ‘users/:user_id/
revisions/:klass’, :klass => “remedy”
user.symptom_revisions ‘users/:user_id/
revisions/:klass’, :klass => “symptom”
end

…which allows in my view to have two links like:

<%= link_to ‘remedy’, remedy_revisions_path(@user) -%> |
<%= link_to ‘symptom’, symptom_revisions_path(@user) -%>

The problem is when clicked, the :klass param is always passed as
“remedy”, even on the symptom_revisions_path.

If I move reverse the order of the 2 named routes, ala…
map.with_options :controller => ‘users’, :action => ‘revisions’ do |
user|
user.symptom_revisions ‘users/:user_id/
revisions/:klass’, :klass => “symptom”
user.remedy_revisions ‘users/:user_id/
revisions/:klass’, :klass => “remedy”
end

Then the symptom :klass param is always passed.

do I have the syntax wrong? I tried the routing lines as separate
lines outside of the with_options block, but same problem.

any ideas?

Steve

I found if I do the route this way…

map.with_options :controller => ‘users’, :action => ‘revisions’ do |
user|
user.remedy_revisions ‘user/:id/:klass/revisions’, :klass =>
‘remedy’
user.symptom_revisions ‘user/:id/:klass/revisions’, :klass =>
‘symptom’
end

(putting the :klass parameter before the string literal ‘revisions’,)
then it works fine.

Steve

Not quite. Now I’m getting this warning:

Route segment “:klass” cannot be optional because it precedes a
required segment. This segment will be required.
Route segment “:klass” cannot be optional because it precedes a
required segment. This segment will be required.

Any suggestions?

Steve

thanks, David. You’re exactly right. I was hoping to do it without
passing in the additional parameter, but oh well.

Steve

Hi –

On Fri, 24 Aug 2007, steve odom wrote:

Steve

end

In my routes I have…

revisions/:klass’, :klass => “symptom”
user.remedy_revisions ‘users/:user_id/
revisions/:klass’, :klass => “remedy”
end

Then the symptom :klass param is always passed.

do I have the syntax wrong? I tried the routing lines as separate
lines outside of the with_options block, but same problem.

any ideas?

My reading of this is as follows. Both your named routes are
generating the same thing:

/users/1/revisions

When it comes time to recognize this path, it matches whichever of the
two is listed first, and sets the optional :klass segment to whatever
that one specifies as the default.

So you need the actual generation of the route to provide enough
information so that the recognition engine can make the right choice.

What I would recommend would be a single named route, like this:

map.with_options :controller => ‘users’,
:action => ‘revisions’ do |user|
user.revisions’/users/:user_id/revisions/:klass’
end

and then in the view:

<%= link_to ‘remedy’, revisions_path(@user, “remedy”) -%> |
<%= link_to ‘symptom’, revisions_path(@user, “symptom”) -%>

which is short for:

revisions_path(:user_id => @user, :klass => “remedy”)

David