# Nested HTTP params on ruby HTTP requests

**URL:** <https://www.ruby-forum.com/t/nested-http-params-on-ruby-http-requests/169496>\
**Category:** Ruby\
**Created:** [June 4, 2009, 1:26pm UTC](https://www.ruby-forum.com/t/nested-http-params-on-ruby-http-requests/169496 "2009-06-04T13:26:26Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![dgaj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b487fb/32.png) [@dgaj](https://www.ruby-forum.com/u/dgaj)\
**Post date:** [June 4, 2009, 1:26pm UTC](https://www.ruby-forum.com/t/nested-http-params-on-ruby-http-requests/169496/1 "2009-06-04T13:26:26Z")

</div>

Hi,

I’m using ruby HTTP classes to send POST requests to a server. The  
problem is that I’m posting some many-levels hierarchical structures on  
my form . When POST parameters are simple key/value there’s no  
serialization problem with form\_data method on PostRequest.

{ :a =\> :b} =\> “a=b”

When the values are arrays it works fine too

{ :a =\> [:b,:c,:d]} =\> “a[]=b&a[]=c&a[]=d”

But when values are hashes serialization doesn’t work as expected.

For example  
{ :a =\> [{:b =\> :c}, {:d =\> :e}]} =\> “a[][b]=c&a[][d]=e”

I don’t know if there’s any other way to do it but browsing the code it  
seems that only one nesting level is supported (maybe is an issue on my  
ruby version 1.8.6).

I developed a tiny serialization method. Is a quick and dirty code (the  
first release I’ve made) but it works for me.

module FormSerializer  
require “erb”  
include ERB::Util

def serialize\_form\_data(data, path = “”,serialized\_params = [])  
if data.kind\_of? Hash  
data.each\_pair{|k,v| token = (path == “” ? url\_encode(k) :  
“[#{url\_encode(k)}]”); serialize\_form\_data(v, “#{path}#{token}”,  
serialized\_params)}  
elsif data.kind\_of? Array  
data.each{|v| serialize\_form\_data(v, “#{path}[]”,  
serialized\_params) }  
else  
#end of recursion  
serialized\_params \<\< “#{path}=#{url\_encode(data)}”  
end

```
return serialized_params.join("&") if (path == "")

```

end

#{ :a =\> :b} = “a=b”  
#{ :a =\> [:b,:c,:d]} = “a[]=b&a[]=c&a[]=d”  
#{ :a =\> :b, :b =\> :c} = “a=b&b=c”  
#{ :a =\> {:b =\> :c}} = “a[b] = c”  
#{ :a =\> [{:b =\> :c}, {:d =\> :e}]} = “a[][b] = c & a[][d] = e”

end

After this I only needed to modify

```
  def form_data(params, sep = '&')
      self.body = serialize_form_data(params)
      self.content_type = 'application/x-www-form-urlencoded'
  end

```

I just finished the code some hours ago, basic testing has been  
performed.  
Hope this will be useful for anyone! 🙂

Best regards

Dave Garcia

---

<div class="post-metadata">

**Author:** ![dgaj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b487fb/32.png) [@dgaj](https://www.ruby-forum.com/u/dgaj)\
**Post date:** [June 4, 2009, 4:11pm UTC](https://www.ruby-forum.com/t/nested-http-params-on-ruby-http-requests/169496/2 "2009-06-04T16:11:53Z")

</div>

Dave Garcia wrote:

> { :a =\> :b} =\> “a=b”
> 
> When the values are arrays it works fine too
> 
> { :a =\> [:b,:c,:d]} =\> “a[]=b&a[]=c&a[]=d”
> 
> But when values are hashes serialization doesn’t work as expected.
> 
> For example  
> { :a =\> [{:b =\> :c}, {:d =\> :e}]} =\> “a[][b]=c&a[][d]=e”

Well, firstly, you didn’t say what framework is parsing this form data.  
But also, in this example you’re doing mixtures of arrays and hashes,  
and I don’t think that’s likely to work. (Of course, feel free to make a  
patch for whatever framework you’re using, and submit it)

I think you’ll have more luck with hashes of hashes:

a[b][c]=d&a[b][d]=e

will probably be deserialised as {‘a’=\>{‘b’=\>{‘c’=\>‘d’,‘e’=\>‘f’}}}

At least, I’m reasonably sure Rails can handle this. Rack had some  
issues with its parsing of nested form-data parameters which may or may  
not have been fixed yet. And if you’re using some other framework with  
its own parameter parsing, then you’ll need to look at that separately.

> I don’t know if there’s any other way to do it but browsing the code it  
> seems that only one nesting level is supported (maybe is an issue on my  
> ruby version 1.8.6).

It’s unlikely to be anything to do with your ruby version, unless the  
deserialisation is being done by some code which is bundled with ruby  
(the CGI library??)

---

<div class="post-metadata">

**Author:** ![dgaj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b487fb/32.png) [@dgaj](https://www.ruby-forum.com/u/dgaj)\
**Post date:** [June 4, 2009, 4:13pm UTC](https://www.ruby-forum.com/t/nested-http-params-on-ruby-http-requests/169496/3 "2009-06-04T16:13:09Z")

</div>

Of course, I meant

```
a[b][c]=d&a[b][e]=f

```

will probably be deserialised as {‘a’=\>{‘b’=\>{‘c’=\>‘d’,‘e’=\>‘f’}}}

---

<div class="post-metadata">

**Author:** ![dgaj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b487fb/32.png) [@dgaj](https://www.ruby-forum.com/u/dgaj)\
**Post date:** [June 4, 2009, 6:15pm UTC](https://www.ruby-forum.com/t/nested-http-params-on-ruby-http-requests/169496/4 "2009-06-04T18:15:11Z")

</div>

Hi Brian,

On the client side:

params = {:a=\>[{:d=\>:e, :b=\>:c}]}  
serialize\_form\_data(params) # “a[][d]=e&a[][b]=c”

On the server side Rails 2.3.2 works fine deserializing my params are :

{“a”=\>[{“b”=\>“c”, “d”=\>“e”}], “action”=\>“show”,  
“controller”=\>“identities”}

Maybe you’re right , I’ll talk with the guys in RoR maybe they’re  
interested.

Best regards

Dave

Brian C. wrote:

> Of course, I meant
> 
> ```
> a[b][c]=d&a[b][e]=f
> 
> ```
> 
> will probably be deserialised as {‘a’=\>{‘b’=\>{‘c’=\>‘d’,‘e’=\>‘f’}}}

---

<div class="post-metadata">

**Author:** ![dgaj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b487fb/32.png) [@dgaj](https://www.ruby-forum.com/u/dgaj)\
**Post date:** [June 4, 2009, 9:45pm UTC](https://www.ruby-forum.com/t/nested-http-params-on-ruby-http-requests/169496/5 "2009-06-04T21:45:55Z")

</div>

Dave Garcia wrote:

> On the client side:
> 
> params = {:a=\>[{:d=\>:e, :b=\>:c}]}  
> serialize\_form\_data(params) # “a[][d]=e&a[][b]=c”
> 
> On the server side Rails 2.3.2 works fine deserializing my params are :
> 
> {“a”=\>[{“b”=\>“c”, “d”=\>“e”}], “action”=\>“show”,  
> “controller”=\>“identities”}

Then I’ve lost you, because that all seems to be working fine (both  
serialize\_form\_data and RoR deserializing it)

So can you give an example of what the problem actually is?

> But when values are hashes serialization doesn’t work as expected.
> 
> For example  
> { :a =\> [{:b =\> :c}, {:d =\> :e}]} =\> “a[][b]=c&a[][d]=e”

Maybe I misunderstood this. Is this what your code actually produces, or  
what you expected it to produce? If not, what did you expect it to  
produce?

---

<div class="post-metadata">

**Author:** ![dgaj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/b487fb/32.png) [@dgaj](https://www.ruby-forum.com/u/dgaj)\
**Post date:** [June 5, 2009, 10:14am UTC](https://www.ruby-forum.com/t/nested-http-params-on-ruby-http-requests/169496/6 "2009-06-05T10:14:56Z")

</div>

Hi Brian,

you’re not lost I explained myself terrible, my fault ;).

Those example of serializations are produced by my code. I tested it  
only sending post request vs rails, but it worked fine with all proposed  
examples.

Sorry for by bad explanation.

Best regards

Dave

Brian C. wrote:

> Dave Garcia wrote:
> 
> > On the client side:
> > 
> > params = {:a=\>[{:d=\>:e, :b=\>:c}]}  
> > serialize\_form\_data(params) # “a[][d]=e&a[][b]=c”
> > 
> > On the server side Rails 2.3.2 works fine deserializing my params are :
> > 
> > {“a”=\>[{“b”=\>“c”, “d”=\>“e”}], “action”=\>“show”,  
> > “controller”=\>“identities”}
> 
> Then I’ve lost you, because that all seems to be working fine (both  
> serialize\_form\_data and RoR deserializing it)
> 
> So can you give an example of what the problem actually is?
> 
> > But when values are hashes serialization doesn’t work as expected.
> > 
> > For example  
> > { :a =\> [{:b =\> :c}, {:d =\> :e}]} =\> “a[][b]=c&a[][d]=e”
> 
> Maybe I misunderstood this. Is this what your code actually produces, or  
> what you expected it to produce? If not, what did you expect it to  
> produce?
