aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authoreileencodes <eileencodes@gmail.com>2017-02-28 08:06:42 -0500
committereileencodes <eileencodes@gmail.com>2017-02-28 08:48:37 -0500
commitca8c21df0fdbf1f03ba2f7fb16b39c3282dc1be0 (patch)
tree2e6c8741d2557795681a3e7521c891ac2e9cfb5e /activerecord
parentc971e7f151e76510196bb4ad21c1d7cbb1d0fe96 (diff)
downloadrails-ca8c21df0fdbf1f03ba2f7fb16b39c3282dc1be0.tar.gz
rails-ca8c21df0fdbf1f03ba2f7fb16b39c3282dc1be0.tar.bz2
rails-ca8c21df0fdbf1f03ba2f7fb16b39c3282dc1be0.zip
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
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb4
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb8
2 files changed, 12 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index 55bf2e0ff0..d35fe9fe50 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -33,6 +33,10 @@ module ActiveRecord
super klass, klass.arel_table, klass.predicate_builder
end
+ def initialize_dup(other) # :nodoc:
+ @association = @association.deep_dup
+ end
+
def target
@association.target
end
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index ede3a44090..3ef322d9e5 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -2107,6 +2107,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
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