Ruby on Rails: Submitting an array in a form
Solution 1
If your html form has input fields with empty square brackets, then they will be turned into an array inside params in the controller.
# Eg multiple input fields all with the same name:
<input type="textbox" name="course[track_codes][]" ...>
# will become the Array
params["course"]["track_codes"]
# with an element for each of the input fields with the same name
Added:
Note that the rails helpers are not setup to do the array trick auto-magically. So you may have to create the name attributes manually. Also, checkboxes have their own issues if using the rails helpers since the checkbox helpers create additional hidden fields to handle the unchecked case.
Solution 2
= simple_form_for @article do |f|
= f.input_field :name, multiple: true
= f.input_field :name, multiple: true
= f.submit
Solution 3
TL;DR version of HTML []
convention:
Array:
<input type="textbox" name="course[track_codes][]", value="a">
<input type="textbox" name="course[track_codes][]", value="b">
<input type="textbox" name="course[track_codes][]", value="c">
Params received:
{ course: { track_codes: ['a', 'b', 'c'] } }
Hash
<input type="textbox" name="course[track_codes][x]", value="a">
<input type="textbox" name="course[track_codes][y]", value="b">
<input type="textbox" name="course[track_codes][z]", value="c">
Params received:
{ course: { track_codes: { x: 'a', y: 'b', z: 'c' } }
Solution 4
I've also found out that if pass your input helper like this you will get an array of courses each one with its own attributes.
# Eg multiple input fields all with the same name:
<input type="textbox" name="course[][track_codes]" ...>
# will become the Array
params["course"]
# where you can get the values of all your attributes like this:
params["course"].each do |course|
course["track_codes"]
end
Solution 5
I just set up a solution using jquery taginput:
http://xoxco.com/projects/code/tagsinput/
I wrote a custom simple_form extension
# for use with: http://xoxco.com/projects/code/tagsinput/
class TagInput < SimpleForm::Inputs::Base
def input
@builder.text_field(attribute_name, input_html_options.merge(value: object.value.join(',')))
end
end
A coffeescrpt snippet:
$('input.tag').tagsInput()
And a tweak to my controller, which sadly has to be slightly specific:
@user = User.find(params[:id])
attrs = params[:user]
if @user.some_field.is_a? Array
attrs[:some_field] = attrs[:some_field].split(',')
end
Related videos on Youtube
William Jones
Updated on July 05, 2022Comments
-
William Jones almost 2 years
I have a model that has an attribute that is an Array. What's the proper way for me to populate that attribute from a form submission?
I know having a form input with a field whose name includes brackets creates a hash from the input. Should I just be taking that and stepping through it in the controller to massage it into an array?
Example to make it less abstract:
class Article serialize :links, Array end
The links variable takes the form of a an array of URLs, i.e.
[["http://www.google.com"], ["http://stackoverflow.com"]]
When I use something like the following in my form, it creates a hash:
<%= hidden_field_tag "article[links][#{url}]", :track, :value => nil %>
The resultant hash looks like this:
"links" => {"http://www.google.com" => "", "http://stackoverflow.com" => ""}
If I don't include the url in the name of the link, additional values clobber each other:
<%= hidden_field_tag "article[links]", :track, :value => url %>
The result looks like this:
"links" => "http://stackoverflow.com"
-
antinome over 11 yearsIf you care about the order of array elements being preserved and want to be really picky about standards, it might be worth reading this question. It sounds like the HTML specs imply, but are not 100% clear, that order should be preserved, but all browsers seem to do it.
-
emptywalls over 9 yearsThis is what I was looking for!
-
Obromios over 9 yearsThis is what I was looking for, but was unable to make it work properly. I have asked for help here, but note that there is an open issue asking for simple_form to support arrays.
-
idmean almost 9 yearsPlease add an explanation what this code does. Like this the answer is not very helpful.
-
DannyB over 8 yearsThe accepted answer should be updated to include this
multiple: true
update, which is clearly the way to go. -
Filipe Esperandio about 7 yearsis there are a way to use simple_form to generate those?
-
Canbey Bilgili over 6 years
f.input :name, input_html: { multiple: true }
could be used for input -
Fabrizio Bertoglio over 5 yearshtml like
<input name="course[track_codes][][field1]" multiple /><input name="course[track_codes][][field2]" multiple />
will generate params{course: {track_codes: [{field1: "yourvalue", field2: "yourvalue"},{field1: "yourvalue", field2: "yourvalue"}]}}
-
Jason Axelson over 5 yearsNote: this answer requires the
simple_form
gem: github.com/plataformatec/simple_form -
bjacobs over 5 years@FilipeEsperandio
f.input "course[track_codes][x]"
-
Alexis Delahaye about 5 years
f.input: name, multiple: true, value: ...
also works with Rails nativeform_for @article do |f|
-
Humayun Naseer almost 3 years@FabrizioBertoglio what if we want to send multiple tags is a single input field?