Rails: controlling order of request parameters in url_for?

I would like to create a URL where the request parameter p = 1 appears at the end of the URL, for example:

/path?foo=X&bar=Y&p=1 

Is it possible to control the ordering of query parameters when creating URLs by:

 url_for(params.merge({ p: page_num })) 

?

Update:

I tried . It turns out that hashes are already ordered in Ruby 1.9, so the code in ActiveSupport::OrderedHash does not actually work. You can verify with Ruby 1.9 that the order is being saved:

 >> 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 sets the p parameter. It seems like any potential solution should decide how url_for the hash.

+4
source share
2 answers

After further digging, I see that it happens that url_for actually sorts the parameters by key lexicographic parameters, regardless of their insertion order in the hash. This seems to be done to aid in caching, as URL parameters are often used for page cache keys.

In short, you cannot do this without a Hash patch, in particular, 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 do I create my own URL for an ordered query string in Rails link_to? .

+2
source

First question: why do you need something like that? The order in which the parameters appear in the URL does not affect how they are selected by the server, as they are the basic key / value associations. Thus, no matter where this parameter appears, it will always be recognized by the server.

However, to answer your question, yes, it is possible. You just need to use ordered hashes. They are available through active support.

 opts = OrderedHash.new opts[:foo] = 'X' opts[:bar] = 'Y' opts[:p] = 1 your_helper_url(opts) 

Gotta do the trick for you.

+1
source

All Articles