Skip to content

Instantly share code, notes, and snippets.

@ahoward
Created April 2, 2009 20:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ahoward/89436 to your computer and use it in GitHub Desktop.
Save ahoward/89436 to your computer and use it in GitHub Desktop.
From 76e59daeacf71d96baa221fe56eca872cf74c59c Mon Sep 17 00:00:00 2001
From: ara.t.howard <ara.t.howard@gmail.com>
Date: Thu, 2 Apr 2009 14:50:58 -0600
Subject: [PATCH] making fields_for generate correctly indexed form fields with multiple nested attributes
---
actionpack/lib/action_view/helpers/form_helper.rb | 12 +++--
actionpack/test/template/form_helper_test.rb | 47 ++++++++++++++++++++-
2 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index a59829b..ad2bfc6 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -1014,7 +1014,7 @@ module ActionView
explicit_child_index = args.last[:child_index] if args.last.is_a?(Hash)
children.map do |child|
- fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index}]", child, args, block)
+ fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(association_name)}]", child, args, block)
end.join
else
fields_for_nested_model(name, explicit_object || association, args, block)
@@ -1032,9 +1032,11 @@ module ActionView
end
end
- def nested_child_index
- @nested_child_index ||= -1
- @nested_child_index += 1
+ def nested_child_index association_name
+ @nested_child_index ||= Hash.new{|h,k| h[k.to_s] = 0}
+ @nested_child_index[association_name]
+ ensure
+ @nested_child_index[association_name] += 1
end
end
end
@@ -1043,4 +1045,4 @@ module ActionView
cattr_accessor :default_form_builder
self.default_form_builder = ::ActionView::Helpers::FormBuilder
end
-end
\ No newline at end of file
+end
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index 654eee4..c99ab4e 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -21,6 +21,9 @@ silence_warnings do
attr_accessor :comments
def comments_attributes=(attributes); end
+
+ attr_accessor :tags
+ def tags_attributes=(attributes); end
end
class Comment
@@ -35,6 +38,18 @@ silence_warnings do
end
end
+ class Tag
+ attr_reader :id
+ attr_reader :post_id
+ def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
+ def save; @id = 1; @post_id = 1 end
+ def new_record?; @id.nil? end
+ def to_param; @id; end
+ def value
+ @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
+ end
+ end
+
class Author < Comment
attr_accessor :post
def post_attributes=(attributes); end
@@ -720,6 +735,36 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_nested_fields_for_on_multiple_nested_attributes_collection_associations
+ @post.comments = []
+ @post.tags = []
+
+ form_for(:post, @post) do |f|
+ f.fields_for(:comments, Comment.new(321)) do |cf|
+ concat cf.text_field(:name)
+ end
+ f.fields_for(:tags, Tag.new(123)) do |tf|
+ concat tf.text_field(:value)
+ end
+ f.fields_for(:tags, Tag.new(456)) do |tf|
+ concat tf.text_field(:value)
+ end
+ end
+
+
+
+ expected = '<form action="http://www.example.com" method="post">' +
+ '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
+ '<input id="post_tags_attributes_0_id" name="post[tags_attributes][0][id]" type="hidden" value="123" />' +
+ '<input id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" size="30" type="text" value="tag #123" />' +
+ '<input id="post_tags_attributes_1_id" name="post[tags_attributes][1][id]" type="hidden" value="456" />' +
+ '<input id="post_tags_attributes_1_value" name="post[tags_attributes][1][value]" size="30" type="text" value="tag #456" />' +
+ '</form>'
+
+ assert_dom_equal expected, output_buffer
+ end
+
def test_fields_for
fields_for(:post, @post) do |f|
concat f.text_field(:title)
@@ -1173,4 +1218,4 @@ class FormHelperTest < ActionView::TestCase
def protect_against_forgery?
false
end
-end
\ No newline at end of file
+end
--
1.5.5.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment