diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 6d6d623..e1f8b4a 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -881,8 +881,9 @@ module ActionView def add_default_name_and_id(options) if options.has_key?("index") - options["name"] ||= tag_name_with_index(options["index"]) - options["id"] ||= tag_id_with_index(options["index"]) + index = (options["index"].is_a?(Symbol) && @object.respond_to?(options["index"])) ? @object.method(options["index"]).call : options["index"] + options["name"] ||= tag_name_with_index(index) + options["id"] ||= tag_id_with_index(index) options.delete("index") elsif defined?(@auto_index) options["name"] ||= tag_name_with_index(@auto_index) @@ -953,7 +954,7 @@ module ActionView def fields_for(record_or_name_or_array, *args, &block) if options.has_key?(:index) - index = "[#{options[:index]}]" + index = (options[:index].is_a?(Symbol) && @object.respond_to?(options[:index])) ? "[#{@object.method(options[:index]).call}]" : "[#{options[:index]}]" elsif defined?(@auto_index) self.object_name = @object_name.to_s.sub(/\[\]$/,"") index = "[#{@auto_index}]" @@ -1029,6 +1030,7 @@ module ActionView explicit_child_index = args.last[:child_index] if args.last.is_a?(Hash) children.map do |child| + explicit_child_index = child.method(explicit_child_index).call if explicit_child_index.is_a?(Symbol) && child.respond_to?(explicit_child_index) fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, args, block) end.join else diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 515f73c..29bda5f 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -787,6 +787,23 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end + def test_nested_fields_for_with_child_method_index_option_override_on_a_nested_attributes_collection_association + @post.comments = [] + + form_for(:post, @post) do |f| + f.fields_for(:comments, Comment.new(321), :child_index => :id) do |cf| + concat cf.text_field(:name) + end + end + + expected = '
' + + '' + + '' + + '
' + + assert_dom_equal expected, output_buffer + end + def test_nested_fields_uses_unique_indices_for_different_collection_associations @post.comments = [Comment.new(321)] @post.tags = [Tag.new(123), Tag.new(456)] @@ -896,6 +913,22 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end + def test_fields_for_with_method_index_option_override + fields_for("post[]", @post, :index => :id) do |f| + concat f.text_field(:title) + concat f.text_area(:body) + concat f.check_box(:secret) + end + + expected = + "" + + "" + + "" + + "" + + assert_dom_equal expected, output_buffer + end + def test_fields_for_without_object fields_for(:post) do |f| concat f.text_field(:title)