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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With