From f93bd0523fe0e459dd596b2e6efff3115fda607d Mon Sep 17 00:00:00 2001 From: David Yip Date: Sun, 8 Mar 2009 22:27:57 -0500 Subject: [PATCH] Don't yield a form builder for nil one-to-one associations. Also added documentation on behavior of one-to-one association builders on associations that evaluate to nil. --- actionpack/lib/action_view/helpers/form_helper.rb | 20 +++++++++++++++++++- actionpack/test/template/form_helper_test.rb | 17 +++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index a589bcb..0c54f6c 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -403,6 +403,19 @@ module ActionView # <% end %> # <% end %> # + # Form builders on models obtained from one-to-one associations only + # execute when the underlying model objects actually exist. In this + # example, if +address+ were nil, then the address builder would have + # yielded no output. To ensure that your forms are rendered, you must + # make sure that your model objects exist when appropriate: + # + # class Person + # def initialize + # @address = Address.new + # end + # ... + # end + # # ==== One-to-many # # Consider a Person class which returns an _array_ of Project instances @@ -1010,7 +1023,12 @@ module ActionView 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) + object = explicit_object || association + if object + fields_for_nested_model(name, object, args, block) + else + "" + end end end diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 654eee4..b39cec1 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -473,6 +473,23 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end + def test_nested_fields_for_does_not_yield_builder_on_nil_association + @post.author = nil + + form_for('post', @post) do |f| + concat f.text_field(:title) + f.fields_for :author do |c| + concat c.text_field(:name) + end + end + + expected = '
' + + '' + + '
' + + assert_dom_equal expected, output_buffer + end + def test_nested_fields_for_with_index_and_parent_fields form_for('post', @post, :index => 1) do |c| concat c.text_field(:title) -- 1.6.0.2 From 392566d94f9c62a0d1a7d01ef37ba6c5c248097f Mon Sep 17 00:00:00 2001 From: Eloy Duran Date: Mon, 9 Mar 2009 10:56:13 +0100 Subject: [PATCH] Moved test to where the other nested attributes tests are and refactored the code a tiny bit. --- actionpack/lib/action_view/helpers/form_helper.rb | 10 ++---- actionpack/test/template/form_helper_test.rb | 34 ++++++++++---------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 0c54f6c..ce03c7c 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -1022,13 +1022,9 @@ module ActionView children.map do |child| fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index}]", child, args, block) end.join - else - object = explicit_object || association - if object - fields_for_nested_model(name, object, args, block) - else - "" - end + + elsif object = explicit_object || association + fields_for_nested_model(name, object, args, block) end end diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index b39cec1..ed90824 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -473,23 +473,6 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end - def test_nested_fields_for_does_not_yield_builder_on_nil_association - @post.author = nil - - form_for('post', @post) do |f| - concat f.text_field(:title) - f.fields_for :author do |c| - concat c.text_field(:name) - end - end - - expected = '
' + - '' + - '
' - - assert_dom_equal expected, output_buffer - end - def test_nested_fields_for_with_index_and_parent_fields form_for('post', @post, :index => 1) do |c| concat c.text_field(:title) @@ -631,6 +614,23 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end + def test_nested_fields_for_on_a_nested_attributes_one_to_one_association_yields_no_builder_if_association_is_nil + @post.author = nil + + form_for('post', @post) do |f| + concat f.text_field(:title) + f.fields_for :author do |c| + concat c.text_field(:name) + end + end + + expected = '
' + + '' + + '
' + + assert_dom_equal expected, output_buffer + end + def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association @post.comments = Array.new(2) { |id| Comment.new(id + 1) } -- 1.6.0.2