Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support recursive models #416

Merged
merged 1 commit into from
May 11, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Metrics/AbcSize:
# Offense count: 3
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 193
Max: 195

# Offense count: 10
Metrics/CyclomaticComplexity:
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
* [#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).
* Your contribution here.

#### Fixes

* [#416](https://github.com/ruby-grape/grape-swagger/pull/416): Support recursive models - [@lest](https://github.com/lest).

### 0.20.3 (May 9, 2016)

#### Features
Expand Down
3 changes: 3 additions & 0 deletions lib/grape-swagger/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@ def parse_request_params(required)
def expose_params_from_model(model)
model_name = model_name(model)

return model_name if @definitions.key?(model_name)
@definitions[model_name] = nil

properties = {}
GrapeSwagger.model_parsers.each do |klass, ancestor|
next unless model.ancestors.map(&:to_s).include?(ancestor)
Expand Down
8 changes: 7 additions & 1 deletion spec/support/model_parsers/entity_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,20 @@ class TypedDefinition < Grape::Entity
expose :prop_file, documentation: { type: File, desc: 'prop_file description' }
expose :prop_json, documentation: { type: JSON, desc: 'prop_json description' }
end

class RecursiveModel < Grape::Entity
expose :name, documentation: { type: String, desc: 'The name.' }
expose :children, using: self, documentation: { type: 'RecursiveModel', is_array: true, desc: 'The child nodes.' }
end
end
end

let(:swagger_definitions_models) do
{
'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'status code' }, 'message' => { 'type' => 'string', 'description' => 'error message' } } },
'ResponseItem' => { 'type' => 'object', 'properties' => { 'id' => { 'type' => 'integer', 'format' => 'int32' }, 'name' => { 'type' => 'string' } } },
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'type' => 'string' }, '$responses' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' } } } }
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'type' => 'string' }, '$responses' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' } } } },
'RecursiveModel' => { 'type' => 'object', 'properties' => { 'name' => { 'type' => 'string', 'description' => 'The name.' }, 'children' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/RecursiveModel' }, 'description' => 'The child nodes.' } } }
}
end

Expand Down
4 changes: 3 additions & 1 deletion spec/support/model_parsers/mock_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@ class QueryInputElement < OpenStruct; end
class QueryInput < OpenStruct; end
class ApiError < OpenStruct; end
class SecondApiError < OpenStruct; end
class RecursiveModel < OpenStruct; end
end
end

let(:swagger_definitions_models) do
{
'ApiError' => { 'type' => 'object', 'properties' => {} },
'UseResponse' => { 'type' => 'object', 'properties' => {} }
'UseResponse' => { 'type' => 'object', 'properties' => {} },
'RecursiveModel' => { 'type' => 'object', 'properties' => {} }
}
end

Expand Down
10 changes: 9 additions & 1 deletion spec/support/model_parsers/representable_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,22 @@ class TypedDefinition < Representable::Decorator
property :prop_file, documentation: { type: File, desc: 'prop_file description' }
property :prop_json, documentation: { type: JSON, desc: 'prop_json description' }
end

class RecursiveModel < Representable::Decorator
include Representable::JSON

property :name, documentation: { type: String, desc: 'The name.' }
property :children, decorator: self, documentation: { type: 'RecursiveModel', is_array: true, desc: 'The child nodes.' }
end
end
end

let(:swagger_definitions_models) do
{
'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'description' => 'status code', 'type' => 'integer', 'format' => 'int32' }, 'message' => { 'description' => 'error message', 'type' => 'string' } } },
'ResponseItem' => { 'type' => 'object', 'properties' => { 'id' => { 'description' => '', 'type' => 'integer', 'format' => 'int32' }, 'name' => { 'description' => '', 'type' => 'string' } } },
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'description' => '', 'type' => 'string' }, 'items' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' }, 'description' => '' } } }
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'description' => '', 'type' => 'string' }, 'items' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' }, 'description' => '' } } },
'RecursiveModel' => { 'type' => 'object', 'properties' => { 'name' => { 'type' => 'string', 'description' => 'The name.' }, 'children' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/RecursiveModel' }, 'description' => 'The child nodes.' } } }
}
end

Expand Down
3 changes: 2 additions & 1 deletion spec/swagger_v2/api_swagger_v2_definitions-models_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ class ModelApi < Grape::API

add_swagger_documentation models: [
::Entities::UseResponse,
::Entities::ApiError
::Entities::ApiError,
::Entities::RecursiveModel
]
end
end
Expand Down