Передача массива в ROR hidden_field

Я пытаюсь передать массив в hidden_field.

Следующий Пользователь имеет 3 роли [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]

Пользователи/edit.html.erb

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

Когда я отправляю форму редактирования, я получаю сообщение об ошибке: ActiveRecord::RecordNotFound в UsersController#update "Не удалось найти роль с ID=245"

Как я могу передать массив в hidden_field?


person JZ.    schedule 06.01.2010    source источник


Ответы (7)


Я бы использовал эту технику.

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

:multiple добавляет как [] в конец атрибута имени, так и multiple="multiple" в элемент ввода, что идеально. Rails использует это внутри, когда генерирует входные данные для массивов, например, в fields_for.

К сожалению, это плохо документировано. Я собираюсь исправить это.

person Grant Hutchins    schedule 27.04.2012
comment
Это работает в Rails 4, хотя он генерирует входные данные с тем же идентификатором. - person Montas; 30.07.2014
comment
У меня не работает в Rails 4.0.2 при использовании form_tag с hidden_field_tag, я бы получил только последнюю роль в params[:role_ids]. Использование hidden_field_tag 'role_ids[]' работает нормально. - person Jeremy F.; 01.05.2015
comment
@Джереми Ф. Это не будет работать с hidden_field_tag, это должно быть hidden_field. - person Grant Hutchins; 25.02.2016
comment
Если вы хотите использовать hidden_field_tag, то <%= hidden_field_tag('role_ids[]', role.id) %> - person courtsimas; 25.07.2018
comment
Документация сейчас есть? Если да, не могли бы вы дать мне ссылку? Спасибо - person Metaphysiker; 28.11.2018

Единственное, что работает для меня (Rails 3.1), это использование hidden_field_tag:

<% @users.roles.each do |role| %>
    <%= hidden_field_tag "user_role_ids[]", role.id %>
<% end %> 
person Matteo Melani    schedule 16.03.2012
comment
Двойные кавычки вокруг user_role_ids[] важны. Одинарные кавычки у меня не сработали. - person Mark Robinson; 17.08.2012

Пытаться:

 <% @user.roles.each_with_index do |role| %>
    <%= f.hidden_field "role_ids[]", :value => role.id %>
 <% end %>
person jamuraa    schedule 06.01.2010
comment
это, кажется, делает хэш - возможно, я поработаю с ним. - person JZ.; 07.01.2010
comment
Это близко. Что в итоге сработало, так это... ‹% f.fields_for :users do |builder| %› ‹%= render 'user_fields', :f =› builder %› ‹% end %› THEN ‹% role = Role.find(:first) %› ‹%= f.hidden_field :role_ids, :value =› role .я бы %> - person JZ.; 09.04.2010
comment
Вот как это сработало для меня ` ‹% @user.roles.each do |role| %› ‹%= f.hidden_field role_ids][, :value =› role.id %› ‹% end %›` .... Не забудьте поменять местами скобки для role_ids][. Если я не переверну скобки, я получу ноль в массиве для параметра role_ids в журналах моего сервера, с обратными скобками это работает как шарм. Не знаю, почему это работает, было бы здорово, если бы кто-нибудь объяснил. - person Zeeshan; 30.10.2011

с использованием Rails 4.2.6

я смог использовать

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

который представил:

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

при попытке использовать hidden_field_tag или 'role_ids[]' детали параметров не были включены в мой form_params.

Это не сработало:

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

потому что он отображает:

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

и виден контроллеру за пределами параметров формы.

person mendokusai    schedule 24.08.2016

попробуйте с:

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

редактировать: примечание - вам нужно будет сделать ids.split(", ") в вашем контроллере, чтобы преобразовать их из строки в массив

person makevoid    schedule 06.01.2010
comment
Закрыть, но все равно не работает. Требуемый вывод: role_ids=›[2, 4] Фактический вывод: role_ids=›2, 4 - person JZ.; 06.01.2010
comment
Тем не менее, я нашел это лучшим решением, просто назвав скрытое поле чем-то вроде :concatenated_role_ids вместо этого и добавив что-то вроде params[:role_ids] ||= params.require(:concatenated_role_ids).split(', ') в начало действия контроллера. - person lucas; 04.10.2019

Я понимаю, что исходный вопрос касался формы Rails form_for, но я только что столкнулся с этой проблемой, пытаясь добавить скрытое поле в форму form_tag. Решение немного другое.

hidden_field_tag продолжал преобразовывать мои идентификаторы в строку, разделенную пробелами, например "1 2 3", а не в массив ["1", "2", "3"], который я хотел. Согласно документации, это известная проблема с hidden_field_tag. Это подход, который в итоге сработал для моей формы Rails 6 form_tag:

В представлении:

<%= hidden_field_tag :role_ids, my_role_ids_array %>

В контроллере:

role_ids = params[:role_ids].split(' ').map(&:to_i)
person richardsonae    schedule 29.02.2020

Можно решить эту проблему с помощью:

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