Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send multiple of the same key/parameter via POST?

If I had to send a bunch of post parameters along an HTTP request, all with the same name, how do I construct the data object to post?

Picture a form with some check boxes, they all have the same name attribute but with different values (if they're checked):

<input name="color" value="red"/>
<input name="color" value="green"/>
<input name="color" value="blue"/>

I want to construct this in ruby (but it needs to be created dynamically depending on what was selected on the form):

data = {
    "color" => "red",
    "color" => "green",
    "color" => "blue"
}

And then send the data to some URL:

Net::HTTP.post_form(url, data)

I cannot control the receiving end, so I have to send the parameters as it expects to receive them. How?

like image 365
Josh M. Avatar asked Sep 25 '13 12:09

Josh M.


2 Answers

data = {
    "color" => "red",
    "color" => "green",
    "color" => "blue"
}

You can't have that, as it would result in Ruby having a single key:

> { a: 1, a: 2, a: 3 }
=> {:a=>3}

But you can have this:

data = {
  colors: [ 'red', 'green', 'blue' ]
}

To achieve that, use this HTML notation:

<input name="color[]" value="red"/>
<input name="color[]" value="green"/>
<input name="color[]" value="blue"/>

This will translate to a GET request as:

?color[]=red&color[]=green&color[]=blue

And to POST as:

color[]: red
color[]: green
color[]: blue

Both will provide, on the server side:

params[ :color ] == [ 'red', 'green', 'blue' ]

If you have to provide params that way, you can take advantage of the array notation of Net::HTTP.post_form. In your HTML:

<input name="color[]" value="red"/>
<input name="color[]" value="green"/>
<input name="color[]" value="blue"/>

Then, in your controller:

colors = params.delete( :color )
Net::HTTP.post_form( uri, { 'color' => colors }.merge( params ) )

Net::HTTP.post_form accept params having an array as value, but do not touch the key notation. So, if you would change the "color" key to the usual parameter convention, you would use "color[]".

That's exactly what you do not want to do in your case. Leaving the key as "color" will achieve the desired result.

like image 120
kik Avatar answered Oct 01 '22 22:10

kik


Can you not simply:

<input name="color[]" value="red"/>
<input name="color[]" value="green"/>
<input name="color[]" value="blue"/>

For other ideas, you can also see this similar post.

like image 41
ljs.dev Avatar answered Oct 01 '22 20:10

ljs.dev