Rails 2: use form_for to build a form covering multiple objects of the same class
This is hopefully a slam dunk for a Rails maven :
I have a form that is supposed to iterate over a set of LineItems
and gather information on each. I am trying to get form_for
and fields_for
to create the proper field names and parameters to give my controller a params hash something like
params[:line_items] = { <line_item.id> => { :rma_reason => "some string", :rma_qty => 2 } }
What I have is:
<% form_for(@object) do |rma_form| %>
<% @order.line_items.each do |item| %>
....
<% fields_for item do |item_f| %>
<%= item_f.text_area :rma_reason %>
开发者_如何学JAVA <%= item_f.text_field :rma_qty, :value => item.quantity, :size=>3 %>
<% end %>
....
<% end %>
<% end %>
And the resultant HTML looks like (what you would expect, I guess):
<textarea id="line_item_id" name="line_item[id]"></textarea>
<input id="line_item_rma_qty" name="line_item[rma_qty]" size="3" type="text" value="1" />
However what I am trying to get (and failing to find any solution beyond going back to ad-hoc HTML tags) is, field names that are indexed by the line_item.id
, e.g. line_item[1928][rma_qty] for instance. This would allow my controller to iterate over each line_item and update it with the given params.
- ... maybe in a pure REST UI, the form should be tied to ONE instance of
LineItem
, and the standard form_for would work - but the user should be able to submit all the changes at once with one form. Is it possible?
When you're nesting form fields, you have to make sure you are chaining the fields_for
methods form the appropriate form builder:
<% rma_form.fields_for :line_item, item do |item_f| %>
by calling fields_for
alone, you were breaking the chain from form_for
and thus the incorrect field names.
the fields_for needs to be called on the main form helper, and a string parameter with magic []
s and an argument indicating which instance should be inserted in the []
s
<% rma_form.fields_for "line_item[]", item do |item_f| %>
so now my tag looks something like
<input id="return_authorization_line_item_1070870205_rma_qty" name="return_authorization[line_item][1070870205][rma_qty]" size="3" type="text" value="1" />
which is peachy.
this classic railscast is a good fields_for intro, and this comment explains the effect of the magic bracket that did what I wanted - other than that, couldn't find this feature documented anywhere.
精彩评论