Skip to content

Commit

Permalink
Changed API of NestedAttributes to take an array, or hash with index …
Browse files Browse the repository at this point in the history
…keys, of hashes that have the id on the inside of the attributes hash and updated the FormBuilder to produce such hashes. Also fixed NestedAttributes with composite ids.

Signed-off-by: Michael Koziarski <michael@koziarski.com>
Signed-off-by: Eloy Duran <eloy.de.enige@gmail.com>
[#1892 state:committed]
  • Loading branch information
cainlevy authored and NZKoz committed Feb 13, 2009
1 parent a650852 commit 5dbc9d4
Show file tree
Hide file tree
Showing 6 changed files with 409 additions and 195 deletions.
26 changes: 18 additions & 8 deletions actionpack/lib/action_view/helpers/form_helper.rb
Expand Up @@ -964,24 +964,34 @@ def nested_attributes_association?(association_name)
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 if args.first.respond_to?(:new_record?)

if association.is_a?(Array)
children = args.first.respond_to?(:new_record?) ? [args.first] : association
children = explicit_object ? [explicit_object] : association
explicit_child_index = args.last[:child_index] if args.last.is_a?(Hash)

children.map do |child|
child_name = "#{name}[#{ child.new_record? ? new_child_id : child.id }]"
@template.fields_for(child_name, child, *args, &block)
fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index}]", child, args, block)
end.join
else
object = args.first.respond_to?(:new_record?) ? args.first : association
fields_for_nested_model(name, explicit_object || association, args, block)
end
end

def fields_for_nested_model(name, object, args, block)
if object.new_record?
@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)
end
end
end

def new_child_id
value = (@child_counter ||= 1)
@child_counter += 1
"new_#{value}"
def nested_child_index
@nested_child_index ||= -1
@nested_child_index += 1
end
end
end
Expand Down
38 changes: 30 additions & 8 deletions actionpack/test/template/form_helper_test.rb
Expand Up @@ -607,6 +607,7 @@ def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to

expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
'</form>'

Expand All @@ -627,8 +628,10 @@ def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collecti

expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_2_name" name="post[comments_attributes][2][name]" size="30" type="text" value="comment #2" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
'</form>'

assert_dom_equal expected, output_buffer
Expand All @@ -648,8 +651,8 @@ def test_nested_fields_for_with_new_records_on_a_nested_attributes_collection_as

expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_new_1_name" name="post[comments_attributes][new_1][name]" size="30" type="text" value="new comment" />' +
'<input id="post_comments_attributes_new_2_name" name="post[comments_attributes][new_2][name]" size="30" type="text" value="new comment" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="new comment" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
'</form>'

assert_dom_equal expected, output_buffer
Expand All @@ -669,8 +672,9 @@ def test_nested_fields_for_with_existing_and_new_records_on_a_nested_attributes_

expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_321_name" name="post[comments_attributes][321][name]" size="30" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_new_1_name" name="post[comments_attributes][new_1][name]" size="30" type="text" value="new comment" />' +
'<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_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
'</form>'

assert_dom_equal expected, output_buffer
Expand All @@ -690,14 +694,32 @@ def test_nested_fields_for_on_a_nested_attributes_collection_association_yields_

expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_321_name" name="post[comments_attributes][321][name]" size="30" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_new_1_name" name="post[comments_attributes][new_1][name]" size="30" type="text" value="new comment" />' +
'<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_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
'</form>'

assert_dom_equal expected, output_buffer
assert_equal yielded_comments, @post.comments
end

def test_nested_fields_for_with_child_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 => 'abc') do |cf|
concat cf.text_field(:name)
end
end

expected = '<form action="http://www.example.com" method="post">' +
'<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
'<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" size="30" type="text" value="comment #321" />' +
'</form>'

assert_dom_equal expected, output_buffer
end

def test_fields_for
fields_for(:post, @post) do |f|
concat f.text_field(:title)
Expand Down

0 comments on commit 5dbc9d4

Please sign in to comment.