mirror of https://github.com/rails/rails
Fix de-duplication of unsaved records for `ActiveRecord::Associations::CollectionProxy#<<`
The existing process was attempting to detect duplicates by storing added records in `Set.new`. When a record is added to `Set.new`, the identity is calculated using `ActiveRecord::Core#hash`, but this value changes before and after saving, so duplicates were not detected before and after saving even for the same object. This PR fixed the problem by using the `#object_id` of the record to detect duplicates. Note that when storing a new object obtained by `ActiveRecord::Base.find` etc., duplicates are not eliminated because the `#object_id` is different. This is the same behavior as the current `ActiveRecord::Associations::CollectionProxy#<<`.
This commit is contained in:
parent
fe6b96afd1
commit
d413d36de2
|
@ -87,7 +87,7 @@ module ActiveRecord
|
|||
def reset
|
||||
super
|
||||
@target = []
|
||||
@replaced_or_added_targets = Set.new
|
||||
@replaced_or_added_targets = Set.new.compare_by_identity
|
||||
@association_ids = nil
|
||||
end
|
||||
|
||||
|
|
|
@ -802,6 +802,26 @@ class InverseBelongsToTests < ActiveRecord::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_with_has_many_inversing_does_not_add_unsaved_duplicate_records_when_collection_is_loaded
|
||||
with_has_many_inversing(Interest) do
|
||||
human = Human.create!
|
||||
human.interests.load
|
||||
interest = Interest.new(human: human)
|
||||
human.interests << interest
|
||||
assert_equal 1, human.interests.size
|
||||
end
|
||||
end
|
||||
|
||||
def test_with_has_many_inversing_does_not_add_saved_duplicate_records_when_collection_is_loaded
|
||||
with_has_many_inversing(Interest) do
|
||||
human = Human.create!
|
||||
human.interests.load
|
||||
interest = Interest.create!(human: human)
|
||||
human.interests << interest
|
||||
assert_equal 1, human.interests.size
|
||||
end
|
||||
end
|
||||
|
||||
def test_recursive_model_has_many_inversing
|
||||
with_has_many_inversing do
|
||||
main = Branch.create!
|
||||
|
|
Loading…
Reference in New Issue