Permalink
Browse files

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 #17117
  • Loading branch information...
eileencodes committed Feb 28, 2017
1 parent c971e7f commit ca8c21df0fdbf1f03ba2f7fb16b39c3282dc1be0
@@ -33,6 +33,10 @@ def initialize(klass, association) #:nodoc:
super klass, klass.arel_table, klass.predicate_builder
end
def initialize_dup(other) # :nodoc:
@association = @association.deep_dup
end
def target
@association.target
end
@@ -2107,6 +2107,14 @@ def test_to_a_should_dup_target
assert_not_equal target.object_id, ary.object_id
end
def test_dup_should_dup_load_target
original = topics(:first).replies
dupped = topics(:first).replies.dup
assert_not_equal original.object_id, dupped.object_id
assert_not_equal original.load_target.object_id, dupped.load_target.object_id
end
def test_merging_with_custom_attribute_writer
bulb = Bulb.new(color: "red")
assert_equal "RED!", bulb.color

0 comments on commit ca8c21d

Please sign in to comment.