Skip to content

Commit eb48291

Browse files
jferriskarmi
authored andcommitted
[MODEL] Fixed #dup behaviour for Elasticsearch::Model
Previously, calling #dup for an Elasticsearch::Model instance would retain the original __elasticsearch__ reference. Given the following example: user = User.create!(name: "Will") other = user.dup other.update!(name: "Bill") You'd end up with two references to "Will" in Elasticsearch, and none for "Bill," because the duplicate instance proxied to the original instance's attributes. With this fix, each duplicate gets its own proxy, so attributes are saved correctly. Closes elastic#517
1 parent 164a247 commit eb48291

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

elasticsearch-model/lib/elasticsearch/model/proxy.rb

+9
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,15 @@ def __elasticsearch__ &block
6666
end
6767
end
6868

69+
# @overload dup
70+
#
71+
# Returns a copy of this object. Resets the __elasticsearch__ proxy so
72+
# the duplicate will build its own proxy.
73+
def initialize_dup(_)
74+
@__elasticsearch__ = nil
75+
super
76+
end
77+
6978
# Common module for the proxy classes
7079
#
7180
module Base

elasticsearch-model/test/unit/proxy_test.rb

+11
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ def changes
6969
assert_equal 'insta barr', DummyProxyModel.new.__elasticsearch__.bar
7070
end
7171

72+
should "reset the proxy target for duplicates" do
73+
model = DummyProxyModel.new
74+
model_target = model.__elasticsearch__.target
75+
duplicate = model.dup
76+
duplicate_target = duplicate.__elasticsearch__.target
77+
78+
assert_not_equal model, duplicate
79+
assert_equal model, model_target
80+
assert_equal duplicate, duplicate_target
81+
end
82+
7283
should "return the proxy class from instance proxy" do
7384
assert_equal Elasticsearch::Model::Proxy::ClassMethodsProxy, DummyProxyModel.new.__elasticsearch__.class.class
7485
end

0 commit comments

Comments
 (0)