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:
parent
e7a8fda033
commit
068f092ced
3 changed files with 29 additions and 3 deletions
|
@ -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*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue