54

I'm trying to pass an array into a hidden_field.

The following User has 3 roles [2,4,5]

>> u = User.find_by_login("lesa")
=> #<User id: 5, login: "lesa", email: "[email protected]", crypted_password: "0f2776e68f1054a2678ad69a3b28e35ad9f42078", salt: "f02ef9e00d16f1b9f82dfcc488fdf96bf5aab4a8", created_at: "2009-12-29 15:15:51", updated_at: "2010-01-06 06:27:16", remember_token: nil, remember_token_expires_at: nil>
>> u.roles.map(&:id)
=> [2, 4, 5]

Users/edit.html.erb

<% form_for @user do |f| -%>
<%= f.hidden_field :role_ids, :value => @user.roles.map(&:id) %>

When I submit my edit form, I receive an error: ActiveRecord::RecordNotFound in UsersController#update "Couldn't find Role with ID=245"

How can I pass an array into the hidden_field?

7 Answers 7

128

I would use this technique.

<% @user.roles.each do |role| %>
    <%= f.hidden_field :role_ids, :multiple => true, :value => role.id %>
<% end %>

:multiple adds both the [] to the end of the name attribute and multiple="multiple" to the input element, which is ideal. Rails uses this internally when it generates inputs for arrays, such as in fields_for.

Unfortunately it is not well-documented. I'm going to look into fixing this.

Sign up to request clarification or add additional context in comments.

6 Comments

This does work in Rails 4 altho it generates inputs with the same id.
Doesn't work for me in Rails 4.0.2 when using form_tag with hidden_field_tag, I would only get the last role in params[:role_ids]. Using hidden_field_tag 'role_ids[]' works fine.
@JeremyF. It won't work with hidden_field_tag, it has to be hidden_field.
If you do want to use hidden_field_tag, then <%= hidden_field_tag('role_ids[]', role.id) %>
Is there now documentation? If yes, could you give me a link? Thanks
|
17

The only thing that works for me (Rails 3.1) is using hidden_field_tag:

<% @users.roles.each do |role| %>
    <%= hidden_field_tag "user_role_ids[]", role.id %>
<% end %> 

1 Comment

The double quotes around user_role_ids[] are important. Single quotes didn't work for me.
3

Try:

 <% @user.roles.each_with_index do |role| %>
    <%= f.hidden_field "role_ids[]", :value => role.id %>
 <% end %>

3 Comments

that seems to make a hash - perhaps I'll hack around with it.
This is close, What ended up working was...<% f.fields_for :users do |builder| %> <%= render 'user_fields', :f => builder %> <% end %> THEN <% role = Role.find(:first) %> <%= f.hidden_field :role_ids, :value => role.id %>
This is how it worked for me ` <% @user.roles.each do |role| %> <%= f.hidden_field "role_ids][", :value => role.id %> <% end %>` .... Remember to reverse the brackets for role_ids][. If I don't reverse the brackets I get nil in the array for role_ids param in my server logs, with reverse brackets it works like charm. Don't know why it works, it would be great if somebody could explain it.
3

using Rails 4.2.6

I was able to use

<% @user.roles.each do |role|
  <%= f.hidden_field :role_ids, :id => role.id, :value => role.id, :multiple => true %>
<% end %>

which rendered:

<input id="12345" value="12345" multiple="multiple" type="hidden" name="role_form[role_ids][]">

trying to use hidden_field_tag or the 'role_ids[]' the param details were not being included in my form_params.

This didn't work:

<% @user.roles.each do |role|
  <%= hidden_field_tag 'role_ids[]', role %>
<% end %>

because it renders:

<input type="hidden" name="role_ids[]" id="role_ids_" value="12345">

and is seen by the controller outside of the form params.

Comments

2

try with:

<%= f.hidden_field :role_ids, :value => @user.roles.map(&:id).join(", ") %>

edit: note - you'll need to do ids.split(", ") in your controller to convert them from a string into an array

2 Comments

Close but it still doesn't work. Required Output: "role_ids"=>["2", "4"] Actual Output: "role_ids"=>"2, 4"
Still, I found this to be the best solution, just naming the hidden field something like :concatenated_role_ids instead and adding something like params[:role_ids] ||= params.require(:concatenated_role_ids).split(', ') to the top of the controller action.
1

I realize the original question involved a Rails form_for form, but I just encountered this problem while trying adding a hidden field to a form_tag form. The solution is slightly different.

The hidden_field_tag kept converting my ids to a space-separated string, like "1 2 3", not the array of ["1", "2", "3"] that I wanted. According to the docs, this is a known problem with hidden_field_tag. This is the approach that ended up working for my Rails 6 form_tag form:

In the view:

<%= hidden_field_tag :role_ids, my_role_ids_array %>

In the controller:

role_ids = params[:role_ids].split(' ').map(&:to_i)

Comments

0

Could solve this kind of issue with :

      <% params[:filter].each do |filter| %>
        <%= hidden_field_tag 'filter[]', filter %>
      <% end %>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.