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.

map.resource nested paths don't always resolve properly

#882

Lets say I allow my user ids to match the id regular expression required below and I define the following route structure in my routes.rb:


map.resources :users, :requirements => { :id => /[a-zA-Z0-9.@:%+;:?&=_+-]+/ }do |user|
  user.resources :messages
  user.resources :books
  user.resources :contacts
end

Given a simple user id like "joe", all routes work as expected:


users/joe
users/joe/messages
users/joe/books
users/joe/contacts

However given a more complex user name like "joe m. black" the only route that works is: users/joe+b.+black (or use %20 signs if you wish).

to get the other routes working I had to define them as follows:


map.user 'users/:id', :requirements => { :id => /[a-zA-Z0-9.@:%+;:?&=_+-]+/
map.user_messages 'users/:id/messages/', :requirements => { :id => /[a-zA-Z0-9.@:%+;:?&=_+-]+/
map.user_books 'users/:id/books', :requirements => { :id => /[a-zA-Z0-9.@:%+;:?&=_+-]+/
map.user_contacts 'users/:id/contacts', :requirements => { :id => /[a-zA-Z0-9.@:%+;:?&=_+-]+/

Stack:


ActionController::RoutingError (No route matches "/users/joe+m.+black/contacts" with {:method=>:get}):
    /vendor/rails/actionpack/lib/action_controller/routing/recognition_optimisation.rb:67:in `recognize_path'
    /vendor/rails/actionpack/lib/action_controller/routing/route_set.rb:384:in `recognize'
    /vendor/rails/actionpack/lib/action_controller/dispatcher.rb:148:in `handle_request'
    /vendor/rails/actionpack/lib/action_controller/dispatcher.rb:107:in `dispatch'
    /vendor/rails/actionpack/lib/action_controller/dispatcher.rb:104:in `synchronize'
    /vendor/rails/actionpack/lib/action_controller/dispatcher.rb:104:in `dispatch'
    /vendor/rails/actionpack/lib/action_controller/dispatcher.rb:120:in `dispatch_cgi'
    /vendor/rails/actionpack/lib/action_controller/dispatcher.rb:35:in `dispatch'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:76:in `process'
    /usr/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/../lib/mongrel/rails.rb:74:in `synchronize'

Reported by Irene · August 22nd, 2008 @ 02:46 PM

State: invalid
Milestone: 2.x
Assigned to: Pratik Pratik
Importance: none

Activity

  1. Peter Wagenet
    Peter Wagenet

    Though this may be a bug, convention has it that you shouldn't use spaces in your urls. Consider using "slugs" such as "joe_m_black" instead of "joe m. black" it will make for nicer looking urls and won't annoy Rails.

    August 23rd, 2008 @ 07:16 PM

  2. Irene
    Irene

    I agree with you that perhaps an id of joe_m_black would work better but we opted to use usernames instead of ids for friendlier URLs (I should have specified that by calling id something else, my apologies) and if someone chose to be identified as Joe M. Black, we support that.

    August 30th, 2008 @ 08:41 PM

  3. Pratik
    Pratik
    • Assigned user set to Pratik
    • State changed from new to invalid

    Looks like your regexp is wrong.

    .

    Thanks!

    December 20th, 2008 @ 05:10 PM

  4. Pratik
    Pratik

    You need to escape the dot ( . )

    December 20th, 2008 @ 05:10 PM

  5. Artem Ignatiev
    Artem Ignatiev

    Just jumped into the same problem.

    Regexp is correct, .'' has no special meaning in character class (inside square brackets).

    Looks like route recognizer with optimizations * works fine when the segment with the dot is the last one segment * dislikes strings like 'some.thing/another_thing' (can't really understand what happens inside to_plain_segments * works fine if the dot in the URL is escaped like @%3E@

    The problem is that generated helper methods (like user_messages_path in the original example) will not escape the dot by itself, and if you want to escape it using to_param method, it will escape percent sign, so your %2E will become %252E

    January 5th, 2009 @ 02:06 PM

  6. Artem Ignatiev
    Artem Ignatiev

    (Whoops, formatting is wrong)

    Just jumped into the same problem.

    Regexp is correct, “@.@” has no special meaning in character class (inside square brackets).

    Looks like route recognizer with optimizations * works fine when the segment with the dot is the last one segment

    • dislikes strings like 'some.thing/another_thing' (can't really understand what happens inside to_plain_segments

    • works fine if the dot in the URL is escaped like @%3E@

    The problem is that generated helper methods (like user_messages_path in the original example) will not escape the dot by itself, and if you want to escape it using to_param method, it will escape percent sign, so your “@some%2Ething@” will become “@some%252Ething@”

    January 5th, 2009 @ 02:08 PM