Rails技术问题:如何通过button_to将数组从视图传至控制器
嘿,作为Rails新手,你碰到的这个问题其实很常见——核心是要把选择的数量和对应的商品ID正确绑定,这样控制器才能准确识别哪件商品买了多少。我来一步步给你讲清楚怎么改:
1. 修正选择框的命名,关联商品ID
你现在的select_tag 'count[]'会生成一组同名的选择框,提交后只会得到一个纯数量数组,但没法对应到具体的商品ID(万一页面商品顺序变动,就完全乱了)。我们需要把选择框的name改成带商品ID的哈希形式:
把原来的:
<%= select_tag 'count[]', options_for_select([0,1,2,3,4,5])%>
改成:
<%= select_tag "count[#{item.id}]", options_for_select([0,1,2,3,4,5]) %>
这样每个选择框的name会是count[1]、count[2](假设商品ID是1、2),提交后控制器拿到的params[:count]会是一个哈希,结构是{ "商品ID" => "选择的数量" },完美对应每个商品的订购数量。
2. 把选择框放到button_to的表单范围内
button_to本质上会生成一个独立的<form>标签,所以你需要把遍历商品的代码放到button_to的块里,这样所有选择框都会被包含在这个表单中,提交时自动带上所有参数,不需要手动填params: { ??? }。
完整的视图代码应该是这样:
<%= button_to 'Place Order', orders_confirm_path, method: :post do %> <% @items.each do |item| %> <li> <%= link_to item.name, item %> <%= select_tag "count[#{item.id}]", options_for_select([0,1,2,3,4,5]) %> </li> <% end %> <% end %>
3. 控制器中获取并处理参数
在OrdersController的confirm动作里,你可以这样拿到并处理提交的数据:
def confirm # params[:count] 是类似 {"1"=>"2", "3"=>"0"} 的哈希,键是商品ID字符串,值是数量字符串 # 我们可以过滤掉数量为0的项,转换成整数方便后续处理 selected_items = params[:count].filter_map do |item_id, quantity| qty = quantity.to_i { item_id: item_id, quantity: qty } if qty > 0 end # 接下来就可以用selected_items来创建订单、计算总价等操作了 # 比如 Order.create!(items: selected_items...) end
可选:用form_tag替代button_to(更灵活)
如果你以后需要在表单里加更多字段(比如备注、收货地址),用form_tag会更灵活,效果和button_to一致:
<%= form_tag orders_confirm_path, method: :post do %> <% @items.each do |item| %> <li> <%= link_to item.name, item %> <%= select_tag "count[#{item.id}]", options_for_select([0,1,2,3,4,5]) %> </li> <% end %> <%= submit_tag 'Place Order', class: 'btn btn-primary' %> <% end %>
额外注意点
- 可以给选择框设置默认选中值,比如
options_for_select([0,1,2,3,4,5], 0),默认选中0; - 如果需要把参数保存到数据库,记得在控制器里设置强参数,允许
count哈希:def order_params params.permit(count: {}) end
内容的提问来源于stack exchange,提问作者Seraph
相关产品推荐
相关产品推荐

