1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Don't save through records twice

If the through record gets created in an `after_create` hook that is
defined before the association is defined (therefore after its
`after_create` hook) get saved twice. This ensures that the through
records are created only once, regardless of the order of the hooks.
This commit is contained in:
Sean Griffin 2014-06-14 09:21:31 -06:00
parent e7a8fda033
commit 068f092ced
3 changed files with 29 additions and 3 deletions

View file

@ -1,3 +1,11 @@
* `has_many :through` associations will no longer save the through record
twice when added in an `after_create` callback defined before the
associations.
Fixes #3798.
*Sean Griffin*
* Add `bin/rake db:purge` task to empty the current database.
*Yves Senn*

View file

@ -184,9 +184,7 @@ module ActiveRecord
before_save :before_save_collection_association
define_non_cyclic_method(save_method) { save_collection_association(reflection) }
# Doesn't use after_save as that would save associations added in after_create/after_update twice
after_create save_method
after_update save_method
after_save save_method
elsif reflection.has_one?
define_method(save_method) { save_has_one_association(reflection) } unless method_defined?(save_method)
# Configures two callbacks instead of a single after_save so that
@ -364,6 +362,7 @@ module ActiveRecord
raise ActiveRecord::Rollback unless saved
end
@new_record_before_save = false
end
# reconstruct the scope now that we know the owner's id

View file

@ -1139,4 +1139,23 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
assert_equal 2, post.lazy_readers_unscope_skimmers.to_a.size
assert_equal 2, post.lazy_people_unscope_skimmers.to_a.size
end
class ClubWithCallbacks < ActiveRecord::Base
self.table_name = 'clubs'
after_create :add_a_member
has_many :memberships, inverse_of: :club, foreign_key: :club_id
has_many :members, through: :memberships
def add_a_member
members << Member.last
end
end
def test_has_many_with_callback_before_association
Member.create!
club = ClubWithCallbacks.create!
assert_equal 1, club.reload.memberships.count
end
end