Ruby on Rails: Submitting an array in a form

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

The links variable takes the form of a an array of URLs, i.e. [[""], [""]]

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" => {"" => "", "" => ""}

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" => ""


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 
# with an element for each of the input fields with the same name


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.

= simple_form_for @article do |f|
  = f.input_field :name, multiple: true
  = f.input_field :name, multiple: true
  = f.submit

TL;DR version of HTML [] convention:

<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'] } }
<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' } }

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 

# where you can get the values of all your attributes like this:
   params["course"].each do |course|

I just set up a solution using jquery taginput:

I wrote a custom simple_form extension

# for use with:

class TagInput < SimpleForm::Inputs::Base

  def input
    @builder.text_field(attribute_name, input_html_options.merge(value: object.value.join(',')))


A coffeescrpt snippet:


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(',')

For those who use simple form, you may consider this solution. Basically need to set up your own input and use it as :array. Then you would need to handle input in your controller level.

#inside lib/utitilies
class ArrayInput < SimpleForm::Inputs::Base
  def input
    @builder.text_field(attribute_name, input_html_options.merge!({value: object.premium_keyword.join(',')}))

#inside view/_form

= f.input :premium_keyword, as: :array, label: 'Premium Keyword (case insensitive, comma seperated)'

#inside controller
def update
  pkw = params[:restaurant][:premium_keyword]
  if pkw.present?
    pkw = pkw.split(", ")
    params[:restaurant][:premium_keyword] = pkw

  if @restaurant.update_attributes(params[:restaurant])
    redirect_to admin_city_restaurants_path, flash: { success: "You have successfully edited a restaurant"}
    render :edit

In your case just change :premium_keyword to the your array field

Need Your Help

How to perform Unwind segue programmatically?

ios segue ios6

Using storyboard this is very easy. You just drag the action to "Exit". But how should I call it from my code?