From 1b78e9bba3bd39c4669ff6c640b7df069185c22c Mon Sep 17 00:00:00 2001 From: Andrew France Date: Sat, 11 Jul 2009 16:38:35 +0200 Subject: Allow fields_for on a nested_attributes association to accept an explicit collection to be used. [#2648 state:resolved] Signed-off-by: Eloy Duran --- actionpack/lib/action_view/helpers/form_helper.rb | 26 +++++++++++----- actionpack/test/template/form_helper_test.rb | 36 +++++++++++++++++++++++ 2 files changed, 55 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 81029102b1..32b9c4a7dd 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -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 diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 8fd018f86d..be15b06372 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -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 = '
' + + '' + + '
' + + 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_on_a_nested_attributes_collection_association_yields_only_builder @post.comments = [Comment.new(321), Comment.new] yielded_comments = [] -- cgit v1.2.3