We cannot send nested hash as a param in HTTP requests. For example, when we would like to send something like this:
{:key => "value", :nested => {:nest => "value"}}
It would be (or should be) mapped like this:
/url/?key=value&nested=%7B%3Anest%3D%3E%5C%22value%5C%22%7D
Doesn't look to good ;) However there is a simple way to convert a nested hash into a params acceptable form. We can convert it to a form, that can be mapped into params like this:
/url/?key=value&nested[nest]=value
Here is method to convert any nested hash to a "one level" equivalent:
module HashConverter def self.encode(value, key = nil, out_hash = {}) case value when Hash then value.each { |k,v| encode(v, append_key(key,k), out_hash) } out_hash when Array then value.each { |v| encode(v, "#{key}[]", out_hash) } out_hash when nil then '' else out_hash[key] = value out_hash end end private def self.append_key(root_key, key) root_key.nil? ? :"#{key}" : :"#{root_key}[#{key.to_s}]" end end
And usage example:
hash = {:level0 => 'value', :nested => {:nest1 => "val1", :nest2 => "val2"}} HashConverter.encode(hash) #=> {:level0=>"value", :"nested[nest1]"=>"val1", :"nested[nest2]"=>"val2"}
This form can be easily mapped into a HTTP url params