Allow fields_for on a nested_attributes association to accept an explicit collection to be used. [#2648 state:resolved]

Signed-off-by: Eloy Duran <eloy.de.enige@gmail.com>
This commit is contained in:
Andrew France 2009-07-11 16:38:35 +02:00 committed by Eloy Duran
parent a44a1257d8
commit 1b78e9bba3
2 changed files with 55 additions and 7 deletions

View File

@ -449,6 +449,15 @@ module ActionView
# <% end %>
# <% end %>
#
# Or a collection to be used:
#
# <% form_for @person, :url => { :action => "update" } do |person_form| %>
# ...
# <% person_form.fields_for :projects, @active_projects do |project_fields| %>
# Name: <%= project_fields.text_field :name %>
# <% end %>
# <% end %>
#
# When projects is already an association on Person you can use
# +accepts_nested_attributes_for+ to define the writer method for you:
#
@ -1037,18 +1046,21 @@ module ActionView
def fields_for_with_nested_attributes(association_name, args, block)
name = "#{object_name}[#{association_name}_attributes]"
association = @object.send(association_name)
explicit_object = args.first.to_model if args.first.respond_to?(:to_model)
association = args.first.to_model if args.first.respond_to?(:to_model)
if association.respond_to?(:new_record?)
association = [association] if @object.send(association_name).is_a?(Array)
elsif !association.is_a?(Array)
association = @object.send(association_name)
end
if association.is_a?(Array)
children = explicit_object ? [explicit_object] : association
explicit_child_index = args.last[:child_index] if args.last.is_a?(Hash)
children.map do |child|
association.map do |child|
fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, args, block)
end.join
else
fields_for_nested_model(name, explicit_object || association, args, block)
elsif association
fields_for_nested_model(name, association, args, block)
end
end

View File

@ -784,6 +784,42 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_an_empty_supplied_attributes_collection
form_for(:post, @post) do |f|
concat f.text_field(:title)
f.fields_for(:comments, []) do |cf|
concat cf.text_field(:name)
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'</form>'
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes_collection
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
form_for(:post, @post) do |f|
concat f.text_field(:title)
f.fields_for(:comments, @post.comments) do |cf|
concat cf.text_field(:name)
end
end
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
'</form>'
assert_dom_equal expected, output_buffer
end
def test_nested_fields_for_on_a_nested_attributes_collection_association_yields_only_builder
@post.comments = [Comment.new(321), Comment.new]
yielded_comments = []