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