diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 994fac00149c4..4914ecc5d0fba 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -939,7 +939,7 @@ def initialize(object_name, object, template, options, proc) end end - (field_helpers - %w(label check_box radio_button fields_for)).each do |selector| + (field_helpers - %w(label check_box radio_button fields_for hidden_field)).each do |selector| src = <<-end_src def #{selector}(method, options = {}) # def text_field(method, options = {}) @template.send( # @template.send( @@ -998,6 +998,11 @@ def check_box(method, options = {}, checked_value = "1", unchecked_value = "0") def radio_button(method, tag_value, options = {}) @template.radio_button(@object_name, method, tag_value, objectify_options(options)) end + + def hidden_field(method, options = {}) + @emitted_hidden_id = true if method == :id + @template.hidden_field(@object_name, method, objectify_options(options)) + end def error_message_on(method, *args) @template.error_message_on(@object, method, *args) @@ -1011,6 +1016,10 @@ def submit(value = "Save changes", options = {}) @template.submit_tag(value, options.reverse_merge(:id => "#{object_name}_submit")) end + def emitted_hidden_id? + @emitted_hidden_id + end + private def objectify_options(options) @default_options.merge(options.merge(:object => @object)) @@ -1045,8 +1054,8 @@ def fields_for_nested_model(name, object, args, block) @template.fields_for(name, object, *args, &block) else @template.fields_for(name, object, *args) do |builder| - @template.concat builder.hidden_field(:id) block.call(builder) + @template.concat builder.hidden_field(:id) unless builder.emitted_hidden_id? end end end diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 357c36d1c0cc7..f22302d3c9055 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -697,6 +697,26 @@ def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to end end + expected = '
' + + '' + + '' + + '' + + '
' + + assert_dom_equal expected, output_buffer + end + + def test_nested_fields_for_with_existing_records_on_a_nested_attributes_one_to_one_association_with_explicit_hidden_field_placement + @post.author = Author.new(321) + + form_for(:post, @post) do |f| + concat f.text_field(:title) + f.fields_for(:author) do |af| + concat af.hidden_field(:id) + concat af.text_field(:name) + end + end + expected = '
' + '' + '' + @@ -718,6 +738,30 @@ def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collecti end end + expected = '' + + '' + + '' + + '' + + '' + + '' + + '
' + + assert_dom_equal expected, output_buffer + end + + def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_explicit_hidden_field_placement + @post.comments = Array.new(2) { |id| Comment.new(id + 1) } + + form_for(:post, @post) do |f| + concat f.text_field(:title) + @post.comments.each do |comment| + f.fields_for(:comments, comment) do |cf| + concat cf.hidden_field(:id) + concat cf.text_field(:name) + end + end + end + expected = '
' + '' + '' + @@ -764,8 +808,8 @@ def test_nested_fields_for_with_existing_and_new_records_on_a_nested_attributes_ expected = '' + '' + - '' + '' + + '' + '' + '
' @@ -799,10 +843,10 @@ def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes expected = '
' + '' + - '' + '' + - '' + + '' + '' + + '' + '
' assert_dom_equal expected, output_buffer @@ -822,8 +866,8 @@ def test_nested_fields_for_on_a_nested_attributes_collection_association_yields_ expected = '
' + '' + - '' + '' + + '' + '' + '
' @@ -841,8 +885,8 @@ def test_nested_fields_for_with_child_index_option_override_on_a_nested_attribut end expected = '
' + - '' + '' + + '' + '
' assert_dom_equal expected, output_buffer @@ -876,18 +920,18 @@ def test_nested_fields_uses_unique_indices_for_different_collection_associations end expected = '
' + - '' + '' + - '' + '' + - '' + + '' + + '' + '' + - '' + '' + - '' + + '' + + '' + '' + - '' + '' + + '' + + '' + '
' assert_dom_equal expected, output_buffer