将数组传递到隐藏字段 ROR

51

我想把一个数组传递到一个隐藏字段中。

以下用户有3个角色 [2,4,5]

>> u = User.find_by_login("lesa")
=> #<User id: 5, login: "lesa", email: "lesa.beaupry@gmail.com", 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) %>

当我提交编辑表单时,收到了一个错误消息:在 UsersController#update 中出现 ActiveRecord::RecordNotFound 错误 "找不到 ID=245 的角色"

如何将一个数组传递到 hidden_field?

7个回答

125

我会使用这个技巧。

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

:multiple 会在name属性的末尾添加[]并在输入元素中添加multiple="multiple",非常理想。Rails在生成数组输入时内部使用此选项,例如在fields_for中。

不幸的是,它的文档不够完善。我将研究修复这个问题。


2
尽管它会生成具有相同id的输入,但这在Rails 4中有效。 - Montas
3
在使用 form_taghidden_field_tag 时,在 Rails 4.0.2 版本中对我无效,只会得到 params[:role_ids] 中的最后一个角色。 使用 hidden_field_tag 'role_ids[]' 却可以正常工作。 - Jeremy F.
1
@JeremyF,使用hidden_field_tag是行不通的,必须使用hidden_field - Grant Hutchins
1
如果您确实想使用hidden_field_tag,则可以使用以下代码:<%= hidden_field_tag('role_ids[]', role.id) %> - courtsimas
现在有文档吗?如果有,能给我一个链接吗?谢谢。 - Metaphysiker

17

对我而言(在Rails 3.1下),唯一有效的方法是使用hidden_field_tag:

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

1
"user_role_ids[]"周围的双引号很重要。单引号对我无效。" - Mark Robinson

3

使用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">

并且被控制器在表单参数之外看到。


3

尝试:

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

1
看起来似乎出了问题 - 也许我得试着解决一下。 - JZ.
这很接近了,最终起作用的是:<% f.fields_for :users do |builder| %> <%= render 'user_fields', :f => builder %> <% end %> 然后 <% role = Role.find(:first) %> <%= f.hidden_field :role_ids, :value => role.id %> - JZ.
2
这是我的解决方法 <% @user.roles.each do |role| %> <%= f.hidden_field "role_ids][", :value => role.id %> <% end %> .... 记得将 role_ids][ 的括号反转。如果我不反转括号,服务器日志中的 role_ids 参数数组会返回 nil,但是使用反转括号就能正常工作。不知道为什么它能正常工作,如果有人能解释一下就太好了。 - Zeeshan

2

尝试使用以下内容:

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

编辑:注意 - 您需要在控制器中执行ids.split(", ")将它们从字符串转换为数组。


1
接近了,但还是不行。所需输出:"role_ids"=>["2", "4"]实际输出:"role_ids"=>"2, 4" - JZ.
1
然而,我发现这是最好的解决方案,只需将隐藏字段命名为 :concatenated_role_ids,并在控制器操作的顶部添加类似于 params[:role_ids] ||= params.require(:concatenated_role_ids).split(', ') 的内容。 - lucas

1
我知道原始问题涉及Rails的form_for表单,但我在尝试向form_tag表单添加隐藏字段时遇到了这个问题。解决方案略有不同。 hidden_field_tag将我的id转换为空格分隔的字符串,例如"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)

0

可以通过以下方式解决这种问题:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接