Skip to content

Commit 2adb8dd

Browse files
tmandkeestolfo
authored andcommittedJul 4, 2019
[Model] Fix naming with inheritance when using Proxy (elastic#887)
* Add naming inheritance tests when using a proxy * Skip circular call to index_name/document_type when Proxy is used and inheritance is enabled
1 parent f9e86de commit 2adb8dd

File tree

2 files changed

+151
-66
lines changed

2 files changed

+151
-66
lines changed
 

‎elasticsearch-model/lib/elasticsearch/model/naming.rb

+6-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,12 @@ def implicit(prop)
9696

9797
if Elasticsearch::Model.settings[:inheritance_enabled]
9898
self.ancestors.each do |klass|
99-
next if klass == self
99+
# When Naming is included in Proxy::ClassMethods the actual model
100+
# is among its ancestors. We don't want to call the actual model
101+
# since it will result in the same call to the same instance of
102+
# Proxy::ClassMethods. To prevent this we also skip the ancestor
103+
# that is the target.
104+
next if klass == self || self.respond_to?(:target) && klass == self.target
100105
break if value = klass.respond_to?(prop) && klass.send(prop)
101106
end
102107
end

‎elasticsearch-model/spec/elasticsearch/model/naming_inheritance_spec.rb

+145-65
Original file line numberDiff line numberDiff line change
@@ -19,105 +19,185 @@
1919

2020
describe 'naming inheritance' do
2121

22-
before(:all) do
23-
class ::TestBase
24-
extend ActiveModel::Naming
22+
context 'without using proxy' do
23+
before(:all) do
24+
TestBase = Class.new do
25+
extend ActiveModel::Naming
2526

26-
extend Elasticsearch::Model::Naming::ClassMethods
27-
include Elasticsearch::Model::Naming::InstanceMethods
28-
end
27+
extend Elasticsearch::Model::Naming::ClassMethods
28+
include Elasticsearch::Model::Naming::InstanceMethods
29+
end
30+
31+
Animal = Class.new TestBase do
32+
extend ActiveModel::Naming
33+
34+
extend Elasticsearch::Model::Naming::ClassMethods
35+
include Elasticsearch::Model::Naming::InstanceMethods
36+
37+
index_name "mammals"
38+
document_type "mammal"
39+
end
40+
41+
Dog = Class.new Animal
2942

30-
class ::Animal < ::TestBase
31-
extend ActiveModel::Naming
43+
module ::MyNamespace
44+
Dog = Class.new Animal
45+
end
46+
47+
Cat = Class.new Animal do
48+
extend ActiveModel::Naming
3249

33-
extend Elasticsearch::Model::Naming::ClassMethods
34-
include Elasticsearch::Model::Naming::InstanceMethods
50+
extend Elasticsearch::Model::Naming::ClassMethods
51+
include Elasticsearch::Model::Naming::InstanceMethods
52+
53+
index_name "cats"
54+
document_type "cat"
55+
end
3556

36-
index_name "mammals"
37-
document_type "mammal"
3857
end
3958

40-
class ::Dog < ::Animal
59+
after(:all) do
60+
remove_classes(TestBase, Animal, MyNamespace, Cat)
4161
end
4262

43-
module ::MyNamespace
44-
class Dog < ::Animal
45-
end
63+
around(:all) do |example|
64+
original_value = Elasticsearch::Model.settings[:inheritance_enabled]
65+
Elasticsearch::Model.settings[:inheritance_enabled] = true
66+
example.run
67+
Elasticsearch::Model.settings[:inheritance_enabled] = original_value
4668
end
4769

48-
class ::Cat < ::Animal
49-
extend ActiveModel::Naming
5070

51-
extend Elasticsearch::Model::Naming::ClassMethods
52-
include Elasticsearch::Model::Naming::InstanceMethods
71+
describe '#index_name' do
72+
73+
it 'returns the default index name' do
74+
expect(TestBase.index_name).to eq('test_bases')
75+
expect(TestBase.new.index_name).to eq('test_bases')
76+
end
5377

54-
index_name "cats"
55-
document_type "cat"
78+
it 'returns the explicit index name' do
79+
expect(Animal.index_name).to eq('mammals')
80+
expect(Animal.new.index_name).to eq('mammals')
81+
82+
expect(Cat.index_name).to eq('cats')
83+
expect(Cat.new.index_name).to eq('cats')
84+
end
85+
86+
it 'returns the ancestor index name' do
87+
expect(Dog.index_name).to eq('mammals')
88+
expect(Dog.new.index_name).to eq('mammals')
89+
end
90+
91+
it 'returns the ancestor index name for namespaced models' do
92+
expect(::MyNamespace::Dog.index_name).to eq('mammals')
93+
expect(::MyNamespace::Dog.new.index_name).to eq('mammals')
94+
end
5695
end
5796

58-
end
97+
describe '#document_type' do
5998

60-
after(:all) do
61-
remove_classes(TestBase, Animal, MyNamespace, Cat)
62-
end
99+
it 'returns nil' do
100+
expect(TestBase.document_type).to be_nil
101+
expect(TestBase.new.document_type).to be_nil
102+
end
63103

64-
around(:all) do |example|
65-
original_value = Elasticsearch::Model.settings[:inheritance_enabled]
66-
Elasticsearch::Model.settings[:inheritance_enabled] = true
67-
example.run
68-
Elasticsearch::Model.settings[:inheritance_enabled] = original_value
69-
end
104+
it 'returns the explicit document type' do
105+
expect(Animal.document_type).to eq('mammal')
106+
expect(Animal.new.document_type).to eq('mammal')
70107

108+
expect(Cat.document_type).to eq('cat')
109+
expect(Cat.new.document_type).to eq('cat')
110+
end
71111

72-
describe '#index_name' do
112+
it 'returns the ancestor document type' do
113+
expect(Dog.document_type).to eq('mammal')
114+
expect(Dog.new.document_type).to eq('mammal')
115+
end
73116

74-
it 'returns the default index name' do
75-
expect(TestBase.index_name).to eq('test_bases')
76-
expect(TestBase.new.index_name).to eq('test_bases')
117+
it 'returns the ancestor document type for namespaced models' do
118+
expect(::MyNamespace::Dog.document_type).to eq('mammal')
119+
expect(::MyNamespace::Dog.new.document_type).to eq('mammal')
120+
end
77121
end
122+
end
123+
124+
context 'when using proxy' do
125+
before(:all) do
126+
TestBase = Class.new do
127+
extend ActiveModel::Naming
128+
129+
include Elasticsearch::Model
130+
end
131+
132+
Animal = Class.new TestBase do
133+
index_name "mammals"
134+
document_type "mammal"
135+
end
136+
137+
Dog = Class.new Animal
78138

79-
it 'returns the explicit index name' do
80-
expect(Animal.index_name).to eq('mammals')
81-
expect(Animal.new.index_name).to eq('mammals')
139+
module MyNamespace
140+
Dog = Class.new Animal
141+
end
82142

83-
expect(Cat.index_name).to eq('cats')
84-
expect(Cat.new.index_name).to eq('cats')
143+
Cat = Class.new Animal do
144+
index_name "cats"
145+
document_type "cat"
146+
end
85147
end
86148

87-
it 'returns the ancestor index name' do
88-
expect(Dog.index_name).to eq('mammals')
89-
expect(Dog.new.index_name).to eq('mammals')
149+
after(:all) do
150+
remove_classes(TestBase, Animal, MyNamespace, Cat)
90151
end
91152

92-
it 'returns the ancestor index name for namespaced models' do
93-
expect(::MyNamespace::Dog.index_name).to eq('mammals')
94-
expect(::MyNamespace::Dog.new.index_name).to eq('mammals')
153+
around(:all) do |example|
154+
original_value = Elasticsearch::Model.settings[:inheritance_enabled]
155+
Elasticsearch::Model.settings[:inheritance_enabled] = true
156+
example.run
157+
Elasticsearch::Model.settings[:inheritance_enabled] = original_value
95158
end
96-
end
97159

98-
describe '#document_type' do
99160

100-
it 'returns nil' do
101-
expect(TestBase.document_type).to be_nil
102-
expect(TestBase.new.document_type).to be_nil
103-
end
161+
describe '#index_name' do
104162

105-
it 'returns the explicit document type' do
106-
expect(Animal.document_type).to eq('mammal')
107-
expect(Animal.new.document_type).to eq('mammal')
163+
it 'returns the default index name' do
164+
expect(TestBase.index_name).to eq('test_bases')
165+
end
108166

109-
expect(Cat.document_type).to eq('cat')
110-
expect(Cat.new.document_type).to eq('cat')
111-
end
167+
it 'returns the explicit index name' do
168+
expect(Animal.index_name).to eq('mammals')
112169

113-
it 'returns the ancestor document type' do
114-
expect(Dog.document_type).to eq('mammal')
115-
expect(Dog.new.document_type).to eq('mammal')
170+
expect(Cat.index_name).to eq('cats')
171+
end
172+
173+
it 'returns the ancestor index name' do
174+
expect(Dog.index_name).to eq('mammals')
175+
end
176+
177+
it 'returns the ancestor index name for namespaced models' do
178+
expect(::MyNamespace::Dog.index_name).to eq('mammals')
179+
end
116180
end
117181

118-
it 'returns the ancestor document type for namespaced models' do
119-
expect(::MyNamespace::Dog.document_type).to eq('mammal')
120-
expect(::MyNamespace::Dog.new.document_type).to eq('mammal')
182+
describe '#document_type' do
183+
184+
it 'returns nil' do
185+
expect(TestBase.document_type).to be_nil
186+
end
187+
188+
it 'returns the explicit document type' do
189+
expect(Animal.document_type).to eq('mammal')
190+
191+
expect(Cat.document_type).to eq('cat')
192+
end
193+
194+
it 'returns the ancestor document type' do
195+
expect(Dog.document_type).to eq('mammal')
196+
end
197+
198+
it 'returns the ancestor document type for namespaced models' do
199+
expect(::MyNamespace::Dog.document_type).to eq('mammal')
200+
end
121201
end
122202
end
123203
end

0 commit comments

Comments
 (0)
Please sign in to comment.