Skip to content

Commit f4cfe9d

Browse files
committed
Merge pull request #416 from lest/recursive-models
Support recursive models
2 parents 4878096 + 9bbac46 commit f4cfe9d

File tree

7 files changed

+29
-5
lines changed

7 files changed

+29
-5
lines changed

.rubocop_todo.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Metrics/AbcSize:
2828
# Offense count: 3
2929
# Configuration parameters: CountComments.
3030
Metrics/ClassLength:
31-
Max: 193
31+
Max: 195
3232

3333
# Offense count: 10
3434
Metrics/CyclomaticComplexity:

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
* [#413](https://github.com/ruby-grape/grape-swagger/pull/413): Move all model parsing logic to separate gems `grape-swagger-entity` and added representable parser `grape-swagger` - [@Bugagazavr](https://github.com/Bugagazavr).
66
* Your contribution here.
77

8+
#### Fixes
9+
10+
* [#416](https://github.com/ruby-grape/grape-swagger/pull/416): Support recursive models - [@lest](https://github.com/lest).
11+
812
### 0.20.3 (May 9, 2016)
913

1014
#### Features

lib/grape-swagger/endpoint.rb

+3
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,9 @@ def parse_request_params(required)
229229
def expose_params_from_model(model)
230230
model_name = model_name(model)
231231

232+
return model_name if @definitions.key?(model_name)
233+
@definitions[model_name] = nil
234+
232235
properties = {}
233236
GrapeSwagger.model_parsers.each do |klass, ancestor|
234237
next unless model.ancestors.map(&:to_s).include?(ancestor)

spec/support/model_parsers/entity_parser.rb

+7-1
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,20 @@ class TypedDefinition < Grape::Entity
111111
expose :prop_file, documentation: { type: File, desc: 'prop_file description' }
112112
expose :prop_json, documentation: { type: JSON, desc: 'prop_json description' }
113113
end
114+
115+
class RecursiveModel < Grape::Entity
116+
expose :name, documentation: { type: String, desc: 'The name.' }
117+
expose :children, using: self, documentation: { type: 'RecursiveModel', is_array: true, desc: 'The child nodes.' }
118+
end
114119
end
115120
end
116121

117122
let(:swagger_definitions_models) do
118123
{
119124
'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'status code' }, 'message' => { 'type' => 'string', 'description' => 'error message' } } },
120125
'ResponseItem' => { 'type' => 'object', 'properties' => { 'id' => { 'type' => 'integer', 'format' => 'int32' }, 'name' => { 'type' => 'string' } } },
121-
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'type' => 'string' }, '$responses' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' } } } }
126+
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'type' => 'string' }, '$responses' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' } } } },
127+
'RecursiveModel' => { 'type' => 'object', 'properties' => { 'name' => { 'type' => 'string', 'description' => 'The name.' }, 'children' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/RecursiveModel' }, 'description' => 'The child nodes.' } } }
122128
}
123129
end
124130

spec/support/model_parsers/mock_parser.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,15 @@ class QueryInputElement < OpenStruct; end
5151
class QueryInput < OpenStruct; end
5252
class ApiError < OpenStruct; end
5353
class SecondApiError < OpenStruct; end
54+
class RecursiveModel < OpenStruct; end
5455
end
5556
end
5657

5758
let(:swagger_definitions_models) do
5859
{
5960
'ApiError' => { 'type' => 'object', 'properties' => {} },
60-
'UseResponse' => { 'type' => 'object', 'properties' => {} }
61+
'UseResponse' => { 'type' => 'object', 'properties' => {} },
62+
'RecursiveModel' => { 'type' => 'object', 'properties' => {} }
6163
}
6264
end
6365

spec/support/model_parsers/representable_parser.rb

+9-1
Original file line numberDiff line numberDiff line change
@@ -179,14 +179,22 @@ class TypedDefinition < Representable::Decorator
179179
property :prop_file, documentation: { type: File, desc: 'prop_file description' }
180180
property :prop_json, documentation: { type: JSON, desc: 'prop_json description' }
181181
end
182+
183+
class RecursiveModel < Representable::Decorator
184+
include Representable::JSON
185+
186+
property :name, documentation: { type: String, desc: 'The name.' }
187+
property :children, decorator: self, documentation: { type: 'RecursiveModel', is_array: true, desc: 'The child nodes.' }
188+
end
182189
end
183190
end
184191

185192
let(:swagger_definitions_models) do
186193
{
187194
'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'description' => 'status code', 'type' => 'integer', 'format' => 'int32' }, 'message' => { 'description' => 'error message', 'type' => 'string' } } },
188195
'ResponseItem' => { 'type' => 'object', 'properties' => { 'id' => { 'description' => '', 'type' => 'integer', 'format' => 'int32' }, 'name' => { 'description' => '', 'type' => 'string' } } },
189-
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'description' => '', 'type' => 'string' }, 'items' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' }, 'description' => '' } } }
196+
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'description' => '', 'type' => 'string' }, 'items' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' }, 'description' => '' } } },
197+
'RecursiveModel' => { 'type' => 'object', 'properties' => { 'name' => { 'type' => 'string', 'description' => 'The name.' }, 'children' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/RecursiveModel' }, 'description' => 'The child nodes.' } } }
190198
}
191199
end
192200

spec/swagger_v2/api_swagger_v2_definitions-models_spec.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ class ModelApi < Grape::API
1010

1111
add_swagger_documentation models: [
1212
::Entities::UseResponse,
13-
::Entities::ApiError
13+
::Entities::ApiError,
14+
::Entities::RecursiveModel
1415
]
1516
end
1617
end

0 commit comments

Comments
 (0)