Skip to content

Commit b26a051

Browse files
committed
Allow entity_name to be called on parent classes
This resolves issue #659.
1 parent 961e7ca commit b26a051

File tree

6 files changed

+113
-31
lines changed

6 files changed

+113
-31
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#### Features
44

5+
* [#794](https://github.com/ruby-grape/grape-swagger/pull/794): Allow entity_name to be inherited, fixes #659 - [@urkle](https://githubcom/urkle).
56
* Your contribution here.
67
* [#793](https://github.com/ruby-grape/grape-swagger/pull/793): Features/inheritance and discriminator - [@MaximeRDY](https://github.com/MaximeRDY).
78

UPGRADING.md

+23-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,29 @@
22

33
### Upgrading to >= 1.2.0
44

5-
Full class name is modified to use `_` separator (e.g. `A_B_C` instead of `A::B::C`).
5+
- The entity_name class method is now called on parent classes for inherited entities. Now you can do this
6+
7+
```ruby
8+
module Some::Long::Module
9+
class Base < Grape::Entity
10+
# ... other shared logic
11+
def self.entity_name
12+
"V2::#{self.to_s.demodulize}"
13+
end
14+
end
15+
16+
def MyEntity < Base
17+
# ....
18+
end
19+
20+
def OtherEntity < Base
21+
# revert back to the default behavior by hiding the method
22+
private_class_method :entity_name
23+
end
24+
end
25+
```
26+
27+
- Full class name is modified to use `_` separator (e.g. `A_B_C` instead of `A::B::C`).
628

729
### Upgrading to >= 1.1.0
830

lib/grape-swagger/doc_methods/data_type.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def parse_multi_type(raw_data_type)
4848
end
4949

5050
def parse_entity_name(model)
51-
if model.methods(false).include?(:entity_name)
51+
if model.respond_to?(:entity_name)
5252
model.entity_name
5353
elsif model.to_s.end_with?('::Entity', '::Entities')
5454
model.to_s.split('::')[0..-2].join('_')

spec/issues/430_entity_definitions_spec.rb

+2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ def self.entity_name
5555
class Class7
5656
class SeventhEntity < Class6::SixthEntity
5757
expose :seventh_thing
58+
59+
private_class_method :entity_name
5860
end
5961
end
6062
end

spec/lib/data_type_spec.rb

+12
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@
4949
it { is_expected.to eq 'MyInteger' }
5050
end
5151

52+
describe 'Types in array with inherited entity_name' do
53+
before do
54+
stub_const 'EntityBase', Class.new
55+
allow(EntityBase).to receive(:entity_name).and_return 'MyInteger'
56+
stub_const 'MyEntity', Class.new(EntityBase)
57+
end
58+
59+
let(:value) { { type: '[MyEntity]' } }
60+
61+
it { is_expected.to eq 'MyInteger' }
62+
end
63+
5264
describe 'Rack::Multipart::UploadedFile' do
5365
let(:value) { { type: Rack::Multipart::UploadedFile } }
5466

spec/swagger_v2/reference_entity_spec.rb

+74-29
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,20 @@ def self.entity_name
2222
expose :title, documentation: { type: 'string', desc: 'Title of the kind.' }
2323
expose :something, documentation: { type: Something, desc: 'Something interesting.' }
2424
end
25+
26+
class Base < Grape::Entity
27+
def self.entity_name
28+
parts = self.to_s.split('::')
29+
30+
"MyAPI::#{parts.last}"
31+
end
32+
33+
expose :title, documentation: { type: 'string', desc: 'Title of the parent.' }
34+
end
35+
36+
class Child < Base
37+
expose :child, documentation: { type: 'string', desc: 'Child property.' }
38+
end
2539
end
2640

2741
class ResponseModelApi < Grape::API
@@ -40,6 +54,16 @@ class ResponseModelApi < Grape::API
4054
present kind, with: Entities::Kind
4155
end
4256

57+
desc 'This returns a child entity',
58+
entity: Entities::Child,
59+
http_codes: [
60+
{ code: 200, message: 'OK', model: Entities::Child }
61+
]
62+
get '/child' do
63+
child = OpenStruct.new text: 'child'
64+
present child, with: Entities::Child
65+
end
66+
4367
add_swagger_documentation # models: [MyAPI::Entities::Something, MyAPI::Entities::Kind]
4468
end
4569
end
@@ -49,36 +73,57 @@ def app
4973
MyAPI::ResponseModelApi
5074
end
5175

52-
subject do
53-
get '/swagger_doc/kind'
54-
JSON.parse(last_response.body)
76+
describe 'kind' do
77+
subject do
78+
get '/swagger_doc/kind'
79+
JSON.parse(last_response.body)
80+
end
81+
82+
it 'should document specified models' do
83+
expect(subject['paths']['/kind']['get']['parameters']).to eq [{
84+
'in' => 'query',
85+
'name' => 'something',
86+
'description' => 'Something interesting.',
87+
'type' => 'SomethingCustom',
88+
'required' => false
89+
}]
90+
91+
expect(subject['definitions'].keys).to include 'SomethingCustom'
92+
expect(subject['definitions']['SomethingCustom']).to eq(
93+
'type' => 'object', 'properties' => { 'text' => { 'type' => 'string', 'description' => 'Content of something.' } }
94+
)
95+
96+
expect(subject['definitions'].keys).to include 'KindCustom'
97+
expect(subject['definitions']['KindCustom']).to eq(
98+
'type' => 'object',
99+
'properties' => {
100+
'title' => { 'type' => 'string', 'description' => 'Title of the kind.' },
101+
'something' => {
102+
'$ref' => '#/definitions/SomethingCustom',
103+
'description' => 'Something interesting.'
104+
}
105+
},
106+
'description' => 'This returns kind and something or an error'
107+
)
108+
end
55109
end
56110

57-
it 'should document specified models' do
58-
expect(subject['paths']['/kind']['get']['parameters']).to eq [{
59-
'in' => 'query',
60-
'name' => 'something',
61-
'description' => 'Something interesting.',
62-
'type' => 'SomethingCustom',
63-
'required' => false
64-
}]
65-
66-
expect(subject['definitions'].keys).to include 'SomethingCustom'
67-
expect(subject['definitions']['SomethingCustom']).to eq(
68-
'type' => 'object', 'properties' => { 'text' => { 'type' => 'string', 'description' => 'Content of something.' } }
69-
)
70-
71-
expect(subject['definitions'].keys).to include 'KindCustom'
72-
expect(subject['definitions']['KindCustom']).to eq(
73-
'type' => 'object',
74-
'properties' => {
75-
'title' => { 'type' => 'string', 'description' => 'Title of the kind.' },
76-
'something' => {
77-
'$ref' => '#/definitions/SomethingCustom',
78-
'description' => 'Something interesting.'
79-
}
80-
},
81-
'description' => 'This returns kind and something or an error'
82-
)
111+
describe 'child' do
112+
subject do
113+
get '/swagger_doc/child'
114+
JSON.parse(last_response.body)
115+
end
116+
117+
it 'should document specified models' do
118+
expect(subject['definitions'].keys).to include 'MyAPI::Child'
119+
expect(subject['definitions']['MyAPI::Child']).to eq(
120+
'type' => 'object',
121+
'properties' => {
122+
'title' => { 'type' => 'string', 'description' => 'Title of the parent.' },
123+
'child' => { 'type' => 'string', 'description' => 'Child property.' }
124+
},
125+
'description' => 'This returns a child entity'
126+
)
127+
end
83128
end
84129
end

0 commit comments

Comments
 (0)