Rails 有多种形式
我在获取 has_many 协会的表格以用于购物篮时遇到了一些麻烦。该视图显示购物篮,并且每个项目都有一个表行。每行包含一个文本字段,以便用户可以设置数量。
问题是,即使第二个项目的数量也发生了变化,只有第一个项目行的数量在参数中传递。
有人可以帮忙吗?
谢谢, Roger
调试器中的 params 输出如下,仅传递了一个 line_item。
(rdb:2624) e params
{"commit"=>"Recalculate",
"authenticity_token"=>"7TKnhmbBPFiKLzVqTipzH8PDyCrOnKiFixGQ37XDGNY=",
"_method"=>"put", "utf8"=>"✓", "action"=>"update", "id"=>"4",
"line_item"=>{"quantity"=>"3", "id"=>"6"}, "controller"=>"baskets"}
应用程序/控制器/basket_controller.rb
class BasketsController < ApplicationController
def update
begin
@basket = Basket.find(params[:id])
# Can't do anything here yet since the correct parameters aren't being passed through.
rescue ActiveRecord::RecordNotFound
logger.error "..."
end
redirect_to basket_path
end
end
应用程序/视图/购物篮/show.html.erb
<%= form_for @basket do |f| %>
<table id="items">
<thead>
<tr>
<th>Name</th>
<th>Quantity</th>
<th>Price</th>
<th></th>
</tr>
</thead>
<tbody>
<% @basket.line_items.each do |item| %>
<%= form_for item do |g| %>
<tr class="<%= cycle('alternate', '') %>">
<td><%= item.product.name %></td>
<td>
<span class="decrement-quantity"><b>-</b></span>
<%= g.text_field :quantity %>
<span class="increment-quantity"><b>+</b></span>
</td>
<td class="price"><%= number_to_currency(item.total_price) %></td>
</tr>
<% end %>
<% end %>
<tr class="totals">
<td>Total</td>
<td><%= @basket.total_quantity %></td>
<td class="price"><%= number_to_currency(@basket.total_price) %></td>
<td></td>
</tr>
</tbody>
</table>
<%= f.submit 'Recalculate' %>
<% end %>
I'm having a bit of trouble getting forms for a has_many association to work for a shopping basket. The view is displaying the basket and has a table row for each item. Each row contains a text field so that the user can set the quantity.
The problem is that only the first item row quantity is being passed through in params, even if the second item's quantity has changed too.
Can anyone help please?
Thanks,
Roger
The output of params in the debugger is below, only one line_item is being passed through.
(rdb:2624) e params
{"commit"=>"Recalculate",
"authenticity_token"=>"7TKnhmbBPFiKLzVqTipzH8PDyCrOnKiFixGQ37XDGNY=",
"_method"=>"put", "utf8"=>"✓", "action"=>"update", "id"=>"4",
"line_item"=>{"quantity"=>"3", "id"=>"6"}, "controller"=>"baskets"}
app/controllers/basket_controller.rb
class BasketsController < ApplicationController
def update
begin
@basket = Basket.find(params[:id])
# Can't do anything here yet since the correct parameters aren't being passed through.
rescue ActiveRecord::RecordNotFound
logger.error "..."
end
redirect_to basket_path
end
end
app/views/baskets/show.html.erb
<%= form_for @basket do |f| %>
<table id="items">
<thead>
<tr>
<th>Name</th>
<th>Quantity</th>
<th>Price</th>
<th></th>
</tr>
</thead>
<tbody>
<% @basket.line_items.each do |item| %>
<%= form_for item do |g| %>
<tr class="<%= cycle('alternate', '') %>">
<td><%= item.product.name %></td>
<td>
<span class="decrement-quantity"><b>-</b></span>
<%= g.text_field :quantity %>
<span class="increment-quantity"><b>+</b></span>
</td>
<td class="price"><%= number_to_currency(item.total_price) %></td>
</tr>
<% end %>
<% end %>
<tr class="totals">
<td>Total</td>
<td><%= @basket.total_quantity %></td>
<td class="price"><%= number_to_currency(@basket.total_price) %></td>
<td></td>
</tr>
</tbody>
</table>
<%= f.submit 'Recalculate' %>
<% end %>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您只是在另一个表单中创建一个新表单。 Rails 不会仅仅因为您将一种形式嵌套在另一种形式中而做出任何神奇的事情 - 这就是导致您所看到的问题的原因。
处理这种情况的方法是使用
fields_for
帮助器 和nested_attributes_for
- 参见 NestedAttributes 了解更多信息。You're just creating a new form within the other form. Rails doesn't do anything magical just because you nest one form within another - which is what's causing the issue you're seeing.
The way to handle this situation is to use the
fields_for
helper andnested_attributes_for
- see NestedAttributes for more information too.我会查看 Railscasts:复杂表单第 1 部分。看完之后,您可能有兴趣观看第 2 部分和第 2 部分。 3.
Ryan Bates 介绍了如何以一种易于理解且易于学习的方式使用 fields_for。
I would checkout Railscasts: Complex Forms Part 1. After you watch that, you may be interested in watching Parts 2 & 3.
Ryan Bates covers using fields_for in an understandable and easy to learn fashion.