Any nested hash in url_for parameters will be harshly flattened using to_s, instead of being converted to the form you might expect—a url that generates the given params hash.
Well that problem is fixed in edge Rails, but it’s a pretty small reason to switch your project to trunk. The patch that fixes this is not directly portable to 1.2.3 because it’s mixed up with other changes in edge.
I absolutely needed this working, so I created a brutish solution by adding a Hash method called flatten_for_url that solves my problem. Stick it in your environment.rb or somewhere in lib/ if you like to keep things organized.
class Hash
def flatten_for_url
nh = HashWithIndifferentAccess.new #Important for use with Rails params
recursive_flatten_for_url(self,nh)
nh
endprivatedef recursive_flatten_for_url(hash,hash_out,keys=[])
hash.each do |k,v|
keys1 = keys.dup
keys1 << k
if v.is_a? Hash
recursive_flatten_for_url(v,hash_out,keys1)
else
keys2 = keys1.dup
key = keys2.shift
key += keys2.collect{ |k2| "[#{k2}]" }.join
hash_out[key] = v
endendendend
My use case is a generic paging helper using Bruce Williams’ excellent paginator gem. All I do is add one method call and things just work.
Nested Hashes in url_for Parameters
You might be surprised that in Rails 1.2.3 the following blows up:
Any nested hash in
url_for
parameters will be harshly flattened usingto_s
, instead of being converted to the form you might expect—a url that generates the given params hash.Well that problem is fixed in edge Rails, but it’s a pretty small reason to switch your project to trunk. The patch that fixes this is not directly portable to 1.2.3 because it’s mixed up with other changes in edge.
I absolutely needed this working, so I created a brutish solution by adding a Hash method called
flatten_for_url
that solves my problem. Stick it in yourenvironment.rb
or somewhere inlib/
if you like to keep things organized.My use case is a generic paging helper using Bruce Williams’ excellent paginator gem. All I do is add one method call and things just work.
url_for(params.flatten_for_url.merge(:page => n))