Skip to content

Commit ca8c21d

Browse files
committed
Dupping a CollectionProxy should dup the load_target
In Rails 3.2 dupping a `CollectionProxy` would dup it's `load_target` as well. That functionality has been broken since the release of Rails 4.0. I hit this in an application upgrade and wondered why duplicating a CollectionProxy and assigning it to a variable stopped working. When calling `dup` on a `CollectionProxy` only the owner (ex. topic) was getting duplicated and the `load_target` would remain in tact with it's original object ID. Dupping the `load_target` is useful for performing a logging operation after records have been destroyed in a method. For example: ``` def transfer_operation saved_replies = topic.replies topic.replies.clear saved_replies.each do |reply| user.update_replies_count! end end ``` This change adds a `initialize_dup` method that performs a `deep_dup` on the `@associatiation` so that the `load_target` is dupped as well. Fixes rails#17117
1 parent c971e7f commit ca8c21d

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

activerecord/lib/active_record/associations/collection_proxy.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ def initialize(klass, association) #:nodoc:
3333
super klass, klass.arel_table, klass.predicate_builder
3434
end
3535

36+
def initialize_dup(other) # :nodoc:
37+
@association = @association.deep_dup
38+
end
39+
3640
def target
3741
@association.target
3842
end

activerecord/test/cases/associations/has_many_associations_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,6 +2107,14 @@ def test_to_a_should_dup_target
21072107
assert_not_equal target.object_id, ary.object_id
21082108
end
21092109

2110+
def test_dup_should_dup_load_target
2111+
original = topics(:first).replies
2112+
dupped = topics(:first).replies.dup
2113+
2114+
assert_not_equal original.object_id, dupped.object_id
2115+
assert_not_equal original.load_target.object_id, dupped.load_target.object_id
2116+
end
2117+
21102118
def test_merging_with_custom_attribute_writer
21112119
bulb = Bulb.new(color: "red")
21122120
assert_equal "RED!", bulb.color

0 commit comments

Comments
 (0)