From 25197d72c6a5cad4b047ff0173c3d42fe10da828 Mon Sep 17 00:00:00 2001 From: Andrew France Date: Fri, 15 May 2009 01:04:36 +0100 Subject: [PATCH] Allow fields_for_with_nested_attributes to accept collections. --- actionpack/lib/action_view/helpers/form_helper.rb | 32 +++++++++++++++--- actionpack/test/template/form_helper_test.rb | 36 +++++++++++++++++++++ 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index beef661..6f05b49 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -446,6 +446,16 @@ module ActionView # <% end %> # <% end %> # + # You can supply a collection to be used: + # + # # Note: @active_projects will have been set in the controller. + # <% 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: # @@ -1007,18 +1017,28 @@ 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 if args.first.respond_to?(:new_record?) - if association.is_a?(Array) - children = explicit_object ? [explicit_object] : association + obj_arg = args.first + if obj_arg.respond_to?(:new_record?) + if @object.send(association_name).is_a?(Array) + records = [obj_arg] + else + records = obj_arg + end + elsif obj_arg.is_a?(Array) + records = obj_arg + else + records = @object.send(association_name) + end + + if records.is_a?(Array) explicit_child_index = args.last[:child_index] if args.last.is_a?(Hash) - children.map do |child| + records.map do |child| fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index}]", child, args, block) end.join else - fields_for_nested_model(name, explicit_object || association, args, block) + fields_for_nested_model(name, records, args, block) end end diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 104649d..0a01f0b 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -638,6 +638,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 = '
' + + '' + + '
' + + 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 = '
' + + '' + + '' + + '' + + '' + + '' + + '
' + + assert_dom_equal expected, output_buffer + end + def test_nested_fields_for_with_new_records_on_a_nested_attributes_collection_association @post.comments = [Comment.new, Comment.new] -- 1.6.0.4