Skip to content

Commit

Permalink
Allow fields_for on a nested_attributes association to accept an expl…
Browse files Browse the repository at this point in the history
…icit collection to be used. [#2648 state:resolved]

Signed-off-by: Eloy Duran <eloy.de.enige@gmail.com>
  • Loading branch information
Odaeus authored and alloy committed Sep 12, 2009
1 parent a44a125 commit 1b78e9b
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 7 deletions.
26 changes: 19 additions & 7 deletions actionpack/lib/action_view/helpers/form_helper.rb
Expand Up @@ -449,6 +449,15 @@ def apply_form_for_options!(object_or_array, options) #:nodoc:
# <% end %>
# <% end %>
#
# Or a collection to be used:
#
# <% form_for @person, :url => { :action => "update" } do |person_form| %>
# ...
# <% person_form.fields_for :projects, @active_projects do |project_fields| %>
# Name: <%= project_fields.text_field :name %>
# <% end %>
# <% end %>
#
# When projects is already an association on Person you can use
# +accepts_nested_attributes_for+ to define the writer method for you:
#
Expand Down Expand Up @@ -1037,18 +1046,21 @@ 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.to_model if args.first.respond_to?(:to_model)
association = args.first.to_model if args.first.respond_to?(:to_model)

if association.respond_to?(:new_record?)
association = [association] if @object.send(association_name).is_a?(Array)
elsif !association.is_a?(Array)
association = @object.send(association_name)
end

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

children.map do |child|
association.map do |child|
fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, args, block)
end.join
else
fields_for_nested_model(name, explicit_object || association, args, block)
elsif association
fields_for_nested_model(name, association, args, block)
end
end

Expand Down
36 changes: 36 additions & 0 deletions actionpack/test/template/form_helper_test.rb
Expand Up @@ -784,6 +784,42 @@ def test_nested_fields_for_with_existing_and_new_records_on_a_nested_attributes_
assert_dom_equal expected, output_buffer
end

def test_nested_fields_for_with_an_empty_supplied_attributes_collection
form_for(:post, @post) do |f|
concat f.text_field(:title)
f.fields_for(:comments, []) do |cf|
concat cf.text_field(:name)
end
end

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

assert_dom_equal expected, output_buffer
end

def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes_collection
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }

form_for(:post, @post) do |f|
concat f.text_field(:title)
f.fields_for(:comments, @post.comments) do |cf|
concat cf.text_field(:name)
end
end

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_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
end

def test_nested_fields_for_on_a_nested_attributes_collection_association_yields_only_builder
@post.comments = [Comment.new(321), Comment.new]
yielded_comments = []
Expand Down

0 comments on commit 1b78e9b

Please sign in to comment.