This article was originally posted onmy blog.
Sometimes an array of data needs to be submitted in an HTML form. A form to send invites to a bunch of users for example. That'd just be a series of email fields; and in the controller; we'd want an array of the emails to iterate over and send invites.
Rails form helpers are set up to have a key and value for each field, so it's not immediately obvious how to send an array of data. But in Rails, there's always a way!
If we append[]
to thename
of a field, it'll be parsed as an array! So for an array of emails to send invites; setting name
asinvites[]
on all the email fields and gives us an array in the controller.
To generate the form, we can use the following code:
<%=form_with(scope: :invites,url:invite_path)do|form|%><%3.timesdo%><!-- id has to be nil to prevent clashes as all fields would have the same id --><%=form.email_fieldnil,id:nil,placeholder:"Email Address"%><%end%><%=form.submit%><%end%>
Passingnil
as the first argument toemail_field
instead of a name gives us the[]
we need for an array. The generated markup looks like:
<formaction="/invite"accept-charset="UTF-8"data-remote="true"method="post"><inputtype="hidden"name="authenticity_token"value="...."><inputplaceholder="Email Address"type="email"name="invites[]"><inputplaceholder="Email Address"type="email"name="invites[]"><inputplaceholder="Email Address"type="email"name="invites[]"><inputtype="submit"name="commit"value="Save Invites"data-disable-with="Save Invites"></form>
On the controller, we can use the submitted data as:
defcreateinvited_users=params.require(:invites)pinvited_users# => ["a@example.com", "b@example.com", "c@example.com"]end
To permit an array parameter in a nested form field, we can use the following pattern:
params.require(:product).permit(tags:[])
It's a little unintuitive but submitting arrays from a form can be a useful tool in your toolbox!
Top comments(2)

what is the difference of your approach and using "multiple: true" ?
<%= form.email_field :email, multiple:true, placeholder: "Email Address" %>

- LocationLondon, UK
- Joined
Themultiple
option relies on the user knowing that they have to provide a comma separated list of email addresses. That's not user friendly in my book. Also, if you do that, Rails parses it into an Array with a single string of the comma separated emails:
"email"=>["a@example.com, b@example.com"]
This means you'd need to do some processing on the server before updating the record. You couldn't just pass the parameters through to Active Record.
Do that make sense?
For further actions, you may consider blocking this person and/orreporting abuse