Rails Has Many Forms
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 bei开发者_如何学编程ng 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 %>
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 and nested_attributes_for
- see NestedAttributes for more information too.
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.
精彩评论