Rails 2 route oddity

I have this in my routes.db

map.connect ‘posts/tags/:id/:chain’,
:requirements => { :controller => ‘posts’, :action => ‘tags’, :chain
=> /chain/ },
:chain => nil

given this path

/posts/tags/onion+funny/chain

params becomes

chain: chain
action: tags
id: onion+funny
controller: posts

params[:id] is NOT ‘onion funny’ as I expect. It is under rails 1.2.5.

Why should it be ‘onion funny’? :id is ‘onion+funny’, that’s what the
url says.
If you wanna have additional logic, I would put it in the controller.

It could be “onion funny” if you did: params[:id].split(“+”).join(" ")
but
what if someone puts a + in their tag?

On Jan 7, 2008 5:33 AM, Kitto [email protected] wrote:

=> /chain/ },
id: onion+funny
controller: posts

params[:id] is NOT ‘onion funny’ as I expect. It is under rails 1.2.5.


Ryan B.

Feel free to add me to MSN and/or GTalk as this email.

yes it’s easily handled in the controller. I just thought it odd that
it worked under rails 1.2.5 but not 2.0.2

I don’t allow + in tags. I also use space as tag separator, since I
figure I display tag cloud using space as separator, so it’s less
confusing to the user if I require them to enter tags that way. To
have compound word tags, I ask them to use - , e.g., pop-culture.
(this makes for a nicer url /posts/tags/pop-culture instead of /posts/
tags/pop%20culture.) Now I wonder if the default comma as tag
separator isn’t the better way to go.

I’m running into this exact same problem. On rails 1.2.6, by default
my paths that included a name with spaces used + instead of the space.
So we have URLs like

/lists/Best+Movies

When I tried upgrading to 2.0, link_to now generates this

/lists/Best Movies

So now all my old URLs are broken. Any ideas? I’m surprised more
people aren’t feeling this pain.

Ben

Or you could just do the cool thing and use commas to seperate the tags?
What if someone wants to put a space in their tags?

“awesome post, large rant, big dog” as examples.

On Jan 7, 2008 11:58 AM, rubynuby [email protected] wrote:

separator isn’t the better way to go.


Ryan B.

Feel free to add me to MSN and/or GTalk as this email.

Oh, I’m no routing expert by any means, so there’s definitely a chance
that something weird in my setup is causing this (especially of others
aren’t have this problem). I looked over my routes.rb and don’t
think I’m doing anything weird, but I’ve certainly been wrong
before.

Any and all ideas about the source of the problem or possible
workarounds would be much appreciated. Thanks!

Ben

OK, after digging around a little bit in actionpack-2.0.2/lib/
action_controller/routing.rb, it looks like Rails has switched from
using CGI.escape to URI.escape. And you can clearly see the difference
in the console

CGI.escape(’ ')
=> “+”

URI.escape(’ ')
=> “%20”

So, my question becomes - does anyone know if this change in behavior
(in the case of spaces) was intentional? Are reason why the old
behavior is not supported? And any ideas on workarounds
(realistically, changing all our links isn’t a great option because
we’ll break existing incoming links to our app).

Thanks!

Ben

OK, I did a little more investigation. It looks like this was
intended. Here is a snippet of actionpack/test/controller/
routing_test.rb


# No + to space in URI escaping, only for query params.
results = rs.recognize_path "/file/hello+world/how+are+you%3F"
assert results, "Recognition should have succeeded"
assert_equal ['hello+world', 'how+are+you?'], results[:path]

# Use %20 for space instead.
results = rs.recognize_path "/file/hello%20world/how%20are%20you

%3F"
assert results, “Recognition should have succeeded”
assert_equal [‘hello world’, ‘how are you?’], results[:path]

Still, this is an unfortunate situation. I would think this would
break quite a few Rails apps when they upgrade to 2.0. Also, %20 isn’t
a particularly pretty separator if you are trying to make your URLs
easier to read. Does anyone know why this was changed? Or workaround
for making spaces escape to something else?

Thanks

Ben