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

fix: duplicate active record objects on inverse_of

Fixes a bug that causes duplicate references to the same object to be
added to the collection association on an active_record object when
inverse_of is used.

In cases where has_many_inversing is set to true, the
set_inverse_instance function calls target= on collection_association during concat
resulting in multiple appends to target. This only occurs for new records. This
PR introduces changes that sets the index so the duplicate object
replaces the original.

Closes issue #43222.

Co-authored-by: Terence Li <terence.li@shopify.com>
Co-authored-by: Dave Rose <dave.rose@shopify.com>
This commit is contained in:
Justin Carvalho 2021-10-13 11:42:39 -04:00
parent f2be2b013c
commit 6f6c441662
2 changed files with 13 additions and 0 deletions

View file

@ -456,6 +456,10 @@ module ActiveRecord
yield(record) if block_given?
if !index && @replaced_or_added_targets.include?(record)
index = @target.index(record)
end
@replaced_or_added_targets << record if inversing || index || record.new_record?
if index

View file

@ -766,6 +766,15 @@ class InverseBelongsToTests < ActiveRecord::TestCase
end
end
def test_with_hash_many_inversing_does_not_add_duplicate_associated_objects
with_has_many_inversing(Interest) do
human = Human.new
interest = Interest.new(human: human)
human.interests << interest
assert_equal 1, human.interests.size
end
end
def test_unscope_does_not_set_inverse_when_incorrect
interest = interests(:trainspotting)
human = interest.human