Skip to content

Commit 127f95f

Browse files
tmandkeestolfo
authored andcommitted
[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 b16871c commit 127f95f

File tree

2 files changed

+146
-61
lines changed

2 files changed

+146
-61
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,12 @@ def implicit(prop)
7979

8080
if Elasticsearch::Model.settings[:inheritance_enabled]
8181
self.ancestors.each do |klass|
82-
next if klass == self
82+
# When Naming is included in Proxy::ClassMethods the actual model
83+
# is among its ancestors. We don't want to call the actual model
84+
# since it will result in the same call to the same instance of
85+
# Proxy::ClassMethods. To prevent this we also skip the ancestor
86+
# that is the target.
87+
next if klass == self || self.respond_to?(:target) && klass == self.target
8388
break if value = klass.respond_to?(prop) && klass.send(prop)
8489
end
8590
end

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

Lines changed: 140 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,45 @@
22

33
describe 'naming inheritance' do
44

5-
before(:all) do
6-
class ::TestBase
7-
extend ActiveModel::Naming
5+
context 'without using proxy' do
6+
before(:all) do
7+
TestBase = Class.new do
8+
extend ActiveModel::Naming
89

9-
extend Elasticsearch::Model::Naming::ClassMethods
10-
include Elasticsearch::Model::Naming::InstanceMethods
11-
end
10+
extend Elasticsearch::Model::Naming::ClassMethods
11+
include Elasticsearch::Model::Naming::InstanceMethods
12+
end
13+
14+
Animal = Class.new TestBase do
15+
extend ActiveModel::Naming
16+
17+
extend Elasticsearch::Model::Naming::ClassMethods
18+
include Elasticsearch::Model::Naming::InstanceMethods
19+
20+
index_name "mammals"
21+
document_type "mammal"
22+
end
23+
24+
Dog = Class.new Animal
1225

13-
class ::Animal < ::TestBase
14-
extend ActiveModel::Naming
26+
module ::MyNamespace
27+
Dog = Class.new Animal
28+
end
29+
30+
Cat = Class.new Animal do
31+
extend ActiveModel::Naming
1532

16-
extend Elasticsearch::Model::Naming::ClassMethods
17-
include Elasticsearch::Model::Naming::InstanceMethods
33+
extend Elasticsearch::Model::Naming::ClassMethods
34+
include Elasticsearch::Model::Naming::InstanceMethods
35+
36+
index_name "cats"
37+
document_type "cat"
38+
end
1839

19-
index_name "mammals"
20-
document_type "mammal"
40+
end
41+
42+
after(:all) do
43+
remove_classes(TestBase, Animal, MyNamespace, Cat)
2144
end
2245

2346
around(:all) do |example|
@@ -27,84 +50,141 @@ class ::Animal < ::TestBase
2750
Elasticsearch::Model.inheritance_enabled = original_value
2851
end
2952

30-
module ::MyNamespace
31-
class Dog < ::Animal
53+
describe '#index_name' do
54+
55+
it 'returns the default index name' do
56+
expect(TestBase.index_name).to eq('test_bases')
57+
expect(TestBase.new.index_name).to eq('test_bases')
3258
end
33-
end
3459

35-
class ::Cat < ::Animal
36-
extend ActiveModel::Naming
60+
it 'returns the explicit index name' do
61+
expect(Animal.index_name).to eq('mammals')
62+
expect(Animal.new.index_name).to eq('mammals')
63+
64+
expect(Cat.index_name).to eq('cats')
65+
expect(Cat.new.index_name).to eq('cats')
66+
end
3767

38-
extend Elasticsearch::Model::Naming::ClassMethods
39-
include Elasticsearch::Model::Naming::InstanceMethods
68+
it 'returns the ancestor index name' do
69+
expect(Dog.index_name).to eq('mammals')
70+
expect(Dog.new.index_name).to eq('mammals')
71+
end
4072

41-
index_name "cats"
42-
document_type "cat"
73+
it 'returns the ancestor index name for namespaced models' do
74+
expect(::MyNamespace::Dog.index_name).to eq('mammals')
75+
expect(::MyNamespace::Dog.new.index_name).to eq('mammals')
76+
end
4377
end
4478

45-
end
79+
describe '#document_type' do
4680

47-
after(:all) do
48-
remove_classes(TestBase, Animal, MyNamespace, Cat)
49-
end
81+
it 'returns nil' do
82+
expect(TestBase.document_type).to be_nil
83+
expect(TestBase.new.document_type).to be_nil
84+
end
5085

51-
around(:all) do |example|
52-
original_value = Elasticsearch::Model.settings[:inheritance_enabled]
53-
Elasticsearch::Model.settings[:inheritance_enabled] = true
54-
example.run
55-
Elasticsearch::Model.settings[:inheritance_enabled] = original_value
56-
end
86+
it 'returns the explicit document type' do
87+
expect(Animal.document_type).to eq('mammal')
88+
expect(Animal.new.document_type).to eq('mammal')
5789

90+
expect(Cat.document_type).to eq('cat')
91+
expect(Cat.new.document_type).to eq('cat')
92+
end
5893

59-
describe '#index_name' do
94+
it 'returns the ancestor document type' do
95+
expect(Dog.document_type).to eq('mammal')
96+
expect(Dog.new.document_type).to eq('mammal')
97+
end
6098

61-
it 'returns the default index name' do
62-
expect(TestBase.index_name).to eq('test_bases')
63-
expect(TestBase.new.index_name).to eq('test_bases')
99+
it 'returns the ancestor document type for namespaced models' do
100+
expect(::MyNamespace::Dog.document_type).to eq('mammal')
101+
expect(::MyNamespace::Dog.new.document_type).to eq('mammal')
102+
end
64103
end
104+
end
65105

66-
it 'returns the explicit index name' do
67-
expect(Animal.index_name).to eq('mammals')
68-
expect(Animal.new.index_name).to eq('mammals')
106+
context 'when using proxy' do
107+
before(:all) do
108+
TestBase = Class.new do
109+
extend ActiveModel::Naming
69110

70-
expect(Cat.index_name).to eq('cats')
71-
expect(Cat.new.index_name).to eq('cats')
111+
include Elasticsearch::Model
112+
end
113+
114+
Animal = Class.new TestBase do
115+
index_name "mammals"
116+
document_type "mammal"
117+
end
118+
119+
Dog = Class.new Animal
120+
121+
module MyNamespace
122+
Dog = Class.new Animal
123+
end
124+
125+
Cat = Class.new Animal do
126+
index_name "cats"
127+
document_type "cat"
128+
end
72129
end
73130

74-
it 'returns the ancestor index name' do
75-
expect(Dog.index_name).to eq('mammals')
76-
expect(Dog.new.index_name).to eq('mammals')
131+
after(:all) do
132+
remove_classes(TestBase, Animal, MyNamespace, Cat)
77133
end
78134

79-
it 'returns the ancestor index name for namespaced models' do
80-
expect(::MyNamespace::Dog.index_name).to eq('mammals')
81-
expect(::MyNamespace::Dog.new.index_name).to eq('mammals')
135+
around(:all) do |example|
136+
original_value = Elasticsearch::Model.settings[:inheritance_enabled]
137+
Elasticsearch::Model.settings[:inheritance_enabled] = true
138+
example.run
139+
Elasticsearch::Model.settings[:inheritance_enabled] = original_value
82140
end
83-
end
84141

85-
describe '#document_type' do
86142

87143
it 'returns the default document type' do
88144
expect(TestBase.document_type).to eq('_doc')
89145
expect(TestBase.new.document_type).to eq('_doc')
90146
end
91147

92-
it 'returns the explicit document type' do
93-
expect(Animal.document_type).to eq('mammal')
94-
expect(Animal.new.document_type).to eq('mammal')
148+
describe '#index_name' do
95149

96-
expect(Cat.document_type).to eq('cat')
97-
expect(Cat.new.document_type).to eq('cat')
98-
end
150+
it 'returns the default index name' do
151+
expect(TestBase.index_name).to eq('test_bases')
152+
end
153+
154+
it 'returns the explicit index name' do
155+
expect(Animal.index_name).to eq('mammals')
99156

100-
it 'returns the ancestor document type' do
101-
expect(Dog.document_type).to eq('mammal')
102-
expect(Dog.new.document_type).to eq('mammal')
157+
expect(Cat.index_name).to eq('cats')
158+
end
159+
160+
it 'returns the ancestor index name' do
161+
expect(Dog.index_name).to eq('mammals')
162+
end
163+
164+
it 'returns the ancestor index name for namespaced models' do
165+
expect(::MyNamespace::Dog.index_name).to eq('mammals')
166+
end
103167
end
104168

105-
it 'returns the ancestor document type for namespaced models' do
106-
expect(::MyNamespace::Dog.document_type).to eq('mammal')
107-
expect(::MyNamespace::Dog.new.document_type).to eq('mammal')
169+
describe '#document_type' do
170+
171+
it 'returns nil' do
172+
expect(TestBase.document_type).to be_nil
173+
end
174+
175+
it 'returns the explicit document type' do
176+
expect(Animal.document_type).to eq('mammal')
177+
178+
expect(Cat.document_type).to eq('cat')
179+
end
180+
181+
it 'returns the ancestor document type' do
182+
expect(Dog.document_type).to eq('mammal')
183+
end
184+
185+
it 'returns the ancestor document type for namespaced models' do
186+
expect(::MyNamespace::Dog.document_type).to eq('mammal')
187+
end
108188
end
109189
end
110190
end

0 commit comments

Comments
 (0)