Rails: control ordering of query parameters in url_for?

ruby, ruby-on-rails-3

Solution

After further digging, I see that what's happening is that `url_for` is actually sorting the parameters by key lexicographically, independent of their insertion order in the hash. Apparently this is being done to aid caching, since URL params are often used for page cache keys.

In short, you can't do it without patching `Hash`, specifically, you need to override `activesupport/core_ext/object/to_param.rb` so that Hash#to_param does not call `.sort` on the return value.

Related question: How to generate custom sorted query string URL in Rails link_to?.

Problem

I'd like to generate a URL where the "p=1" query param appears at the end of the URL, like: ``` /path?foo=X&bar=Y&p=1 ``` Is it possible to control the ordering of query parameters when generating URLs via: ``` url_for(params.merge({ p: page_num })) ``` ? Update: I tried ChuckE's suggestion below. It turns out that in Ruby 1.9 Hashes are already ordered, so the code in `ActiveSupport::OrderedHash` is effectively no-op'd. You can verify with Ruby 1.9 that order is preserved: ``` >> h = {one: 1, two: 2, three: 3 } {:one=>1, :two=>2, :three=>3} >> f = h.except(:one) {:two=>2, :three=>3} >> f[:one] = 1 1 >> f {:two=>2, :three=>3, :one=>1} ``` However, `url_for` still puts the "p" param first. It seems that any potential solution will need to address how `url_for` iterates the hash.

Original source