Skip to content

Commit c61db5f

Browse files
dmoss18LeFnord
authored andcommitted
Parse route_param type for nested endpoints (ruby-grape#847)
* Fix documentation of `route_param` type when used with nested endpoints * Rubocop fixes * Rubocop fixes * grape 1.6 Co-authored-by: peter scholz <[email protected]>
1 parent 5b08872 commit c61db5f

File tree

4 files changed

+72
-3
lines changed

4 files changed

+72
-3
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
### 1.4.4
2+
3+
#### Fixes
4+
5+
* [#840](https://github.com/ruby-grape/grape-swagger/pull/847): Fix documentation of `route_param` type when used with nested endpoints - [@dmoss18](https://github.com/dmoss18)
6+
17
### 1.4.3 (January 5, 2022)
28

39
#### Fixes

Gemfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ ruby RUBY_VERSION
66

77
gemspec
88

9-
gem 'grape', case version = ENV.fetch('GRAPE_VERSION', '>= 1.5.0')
9+
gem 'grape', case version = ENV.fetch('GRAPE_VERSION', '~> 1.6')
1010
when 'HEAD'
1111
{ git: 'https://github.com/ruby-grape/grape' }
1212
else
1313
version
1414
end
1515

16-
gem ENV['MODEL_PARSER'] if ENV.key?('MODEL_PARSER')
16+
gem ENV.fetch('MODEL_PARSER', nil) if ENV.key?('MODEL_PARSER')
1717

1818
group :development, :test do
1919
gem 'bundler'

lib/grape-swagger/swagger_2/endpoint.rb

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,13 +348,39 @@ def build_request_params(route, settings)
348348
end
349349

350350
def merge_params(route)
351+
path_params = get_path_params(route.app&.inheritable_setting&.namespace_stackable)
351352
param_keys = route.params.keys
353+
354+
# Merge path params options into route params
355+
route_params = route.params
356+
route_params.each_key do |key|
357+
path = path_params[key] || {}
358+
params = route_params[key]
359+
params = {} unless params.is_a? Hash
360+
route_params[key] = path.merge(params)
361+
end
362+
352363
route.params.delete_if { |key| key.is_a?(String) && param_keys.include?(key.to_sym) }.to_a
353364
end
354365

366+
# Iterates over namespaces recursively
367+
# to build a hash of path params with options, including type
368+
def get_path_params(stackable_values)
369+
params = {}
370+
return param unless stackable_values
371+
return params unless stackable_values.is_a? Grape::Util::StackableValues
372+
373+
stackable_values&.new_values&.dig(:namespace)&.each do |namespace|
374+
space = namespace.space.to_s.gsub(':', '')
375+
params[space] = namespace.options || {}
376+
end
377+
inherited_params = get_path_params(stackable_values.inherited_values)
378+
inherited_params.merge(params)
379+
end
380+
355381
def default_type(params)
356382
default_param_type = { required: true, type: 'Integer' }
357-
params.each { |param| param[-1] = param.last == '' ? default_param_type : param.last }
383+
params.each { |param| param[-1] = param.last.empty? ? default_param_type : param.last }
358384
end
359385

360386
def expose_params(value)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
describe '#847 route_param type is included in documentation' do
6+
let(:app) do
7+
Class.new(Grape::API) do
8+
resource :accounts do
9+
route_param :account_number, type: String do
10+
resource :records do
11+
route_param :id do
12+
get do
13+
{ message: 'hello world' }
14+
end
15+
end
16+
end
17+
end
18+
end
19+
20+
add_swagger_documentation
21+
end
22+
end
23+
let(:parameters) { subject['paths']['/accounts/{account_number}/records/{id}']['get']['parameters'] }
24+
25+
subject do
26+
get '/swagger_doc'
27+
JSON.parse(last_response.body)
28+
end
29+
30+
specify do
31+
account_number_param = parameters.find { |param| param['name'] == 'account_number' }
32+
expect(account_number_param['type']).to eq 'string'
33+
id_param = parameters.find { |param| param['name'] == 'id' }
34+
# Default is still integer
35+
expect(id_param['type']).to eq 'integer'
36+
end
37+
end

0 commit comments

Comments
 (0)