Skip to content

Commit

Permalink
Pushing a record onto a has_many :through sets the association's fore…
Browse files Browse the repository at this point in the history
…ign key to the associate's primary key and adds it to the correct association. Closes #5829.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4792 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information
jeremy committed Aug 20, 2006
1 parent e96c582 commit 70577d0
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 13 deletions.
2 changes: 1 addition & 1 deletion activerecord/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
*SVN*

* Pushing a record onto a has_many :through sets the association's foreign key to the associate's primary key. #5815 [josh@hasmanythrough.com]
* Pushing a record onto a has_many :through sets the association's foreign key to the associate's primary key and adds it to the correct association. #5815, #5829 [josh@hasmanythrough.com]

* PostgreSQL: simplify index introspection query. #5819 [stephen_purcell@yahoo.com]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ def <<(*records)
raise_on_type_mismatch(associate)
raise ActiveRecord::HasManyThroughCantAssociateNewRecords.new(@owner, through) unless associate.respond_to?(:new_record?) && !associate.new_record?

@target << klass.with_scope(:create => construct_join_attributes(associate)) { klass.create! }
@owner.send(@reflection.through_reflection.name).proxy_target << klass.with_scope(:create => construct_join_attributes(associate)) { klass.create! }
@target << associate
end
end

Expand Down
35 changes: 24 additions & 11 deletions activerecord/test/associations_join_model_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -372,17 +372,30 @@ def test_raise_error_when_adding_new_record_to_has_many_through
def test_create_associate_when_adding_to_has_many_through
count = posts(:thinking).tags.count
push = Tag.create!(:name => 'pushme')
assert_nothing_raised { posts(:thinking).tags << push }
assert_equal(count + 1, posts(:thinking).tags.size)
assert_equal(count + 1, posts(:thinking).tags(true).size)

assert_nothing_raised { posts(:thinking).tags.create!(:name => 'foo') }
assert_equal(count + 2, posts(:thinking).tags.size)
assert_equal(count + 2, posts(:thinking).tags(true).size)

assert_nothing_raised { posts(:thinking).tags.concat(Tag.create!(:name => 'abc'), Tag.create!(:name => 'def')) }
assert_equal(count + 4, posts(:thinking).tags.size)
assert_equal(count + 4, posts(:thinking).tags(true).size)
post_thinking = posts(:thinking)
assert_nothing_raised { post_thinking.tags << push }
assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
message = "Expected a Tag in tags collection, got #{wrong.class}.")
assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
assert_equal(count + 1, post_thinking.tags.size)
assert_equal(count + 1, post_thinking.tags(true).size)

assert_nothing_raised { post_thinking.tags.create!(:name => 'foo') }
assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
message = "Expected a Tag in tags collection, got #{wrong.class}.")
assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
assert_equal(count + 2, post_thinking.tags.size)
assert_equal(count + 2, post_thinking.tags(true).size)

assert_nothing_raised { post_thinking.tags.concat(Tag.create!(:name => 'abc'), Tag.create!(:name => 'def')) }
assert_nil( wrong = post_thinking.tags.detect { |t| t.class != Tag },
message = "Expected a Tag in tags collection, got #{wrong.class}.")
assert_nil( wrong = post_thinking.taggings.detect { |t| t.class != Tagging },
message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
assert_equal(count + 4, post_thinking.tags.size)
assert_equal(count + 4, post_thinking.tags(true).size)
end

def test_adding_junk_to_has_many_through_should_raise_type_mismatch
Expand Down

0 comments on commit 70577d0

Please sign in to comment.