<%= form_for list do |f| %> <!-- This might be an issue in production mode -->
<%= f.fields_for l = list.list_items.build, index: l.id do |list_item| %>
<td><%= list_item.check_box :user_item_id, { checked: false, include_hidden: false }, item.id, "nil" %></td> <!-- checkboxes seem problematic, try check_box_tag? -->
<td><%= item.name %></td>
<td>$<%= number_with_precision(item.price, :precision => 2) %></td>
<td><%= list_item.number_field :quantity,
min: 1,
class: "num"%></td>
<% end %>
<% end %>
如果我的页面上有三个这样的,并且所有三个都被选中,Rails将为每个表单发送一个额外的未经检查的值。这是为什么?
Parameters: {"utf8"=>"✓", "authenticity_token"=>"sn2HLFvVLX7ZFxBTHvRGz25H+bbyiVl8E8Kok5J7788q8WA33U8RpWmLXjU2GTjD2ybW7RMaiX1CwLJ6oCLXmQ==", "list"=>{"list_item"=>[{"user_item_id"=>"nil"}, {"user_item_id"=>"19", "quantity"=>"1"}, {"user_item_id"=>"nil"}, {"user_item_id"=>"20", "quantity"=>"2"}, {"user_item_id"=>"nil"}, {"user_item_id"=>"21", "quantity"=>"3"}], "name"=>""}, "commit"=>"Create List"}
但是,如果我关闭了隐藏字段,那么在未选中前一个框的情况下,我的表单中的其他问题会“窃取”彼此的数据。例如,我在第一个表单中取消选中:
参数:{“utf8”=&gt;“✓”,“authenticity_token”=&gt;“qszyk + q + pJ77WuDh2 / K2S8lTuBD99DptwqeEdDI4U + 4yQBWIbCSYRUvGrofzH8hHfDKXSxxn6myTpZ6dAGFruA ==”,“list”=&gt; {“list_item”=&gt; [ {“quantity”=&gt;“1”,“user_item_id”=&gt;“20”},{“quantity”=&gt;“2”,“user_item_id”=&gt;“21”},{“数量”=&gt; ;“3”}],“name”=&gt;“”},“commit”=&gt;“创建列表”}
注意第一个未经检查的表单如何忽略将user_item_id设置为“nil”,而是完全离开param并偷走下一个表单的user_item_id,从而弄乱了我的数量值(我设置为与之前相同)。
为什么会这样?
PS:我最初只有“nil”,但这样做可以防止在任何情况下传递未经检查的值,而且我遇到的问题就像我上面发布的那样从对方窃取价值。如果有人能告诉我如何制作它,那么未经检查的框意味着我的fields_for将不会被提交,那将是很棒的。答案 0 :(得分:1)
由rails完成,以便在取消选中复选框时发送正确的值。
当您不勾选复选框时,隐藏字段的值(由复选框帮助程序添加)会到达您的服务器,因为浏览器不会发送未选中的复选框。
另一方面,当您检查它时,具有相同名称的最后一个值获胜,这意味着已检查的值将被发送到服务器,一切都将按预期工作。
疑难杂症
HTML规范说未经检查的复选框不成功, 因此Web浏览器不会发送它们。不幸的是这引入了 问题:如果发票模型有付费标志,并且形式为 编辑付费发票,用户取消选中其复选框,不付款 参数被发送。所以,任何质量分配成语都像 @ invoice.update(params [:invoice])不会更新标志。
为了防止这种情况,帮助者之前生成一个辅助隐藏字段 非常复选框。隐藏字段具有相同的名称和它的名称 属性模仿未选中的复选框。
这样,客户端或者只发送隐藏字段(代表 复选框未选中)或两个字段。自HTML 规范说,键/值对必须以相同的顺序发送 它们出现在表单中,参数提取得到最后一个 在查询字符串中出现任何重复键,适用于 普通形式。