Skip to content

Commit 383a1ca

Browse files
committed
support array with index
1 parent 58bfd61 commit 383a1ca

8 files changed

Lines changed: 65 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* [#1252](https://github.com/ruby-grape/grape/pull/1252): Allow default to be a subset or equal to allowed values without raising IncompatibleOptionValues - [@jeradphelps](https://github.com/jeradphelps).
1212
* [#1255](https://github.com/ruby-grape/grape/pull/1255): Allow param type definition in `route_param` - [@namusyaka](https://github.com/namusyaka).
1313
* [#1257](https://github.com/ruby-grape/grape/pull/1257): Allow Proc, Symbol or String in `rescue_from with: ...` - [@namusyaka](https://github.com/namusyaka).
14+
* [#1261](https://github.com/ruby-grape/grape/pull/1261): support array with index - [@itoufo](https://github.com/itoufo).
1415
* Your contribution here.
1516

1617
#### Fixes

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,31 @@ params do
912912
end
913913
```
914914

915+
If type is Array, It support following kinds of parameter.
916+
#### Array
917+
```sh
918+
#without index
919+
curl -X POST http://localhost:9292/api/v1/preference.json -d \
920+
&preferences[][key]=foo \
921+
&preferences[][value]=100 \
922+
&preferences[][key]=bar \
923+
&preferences[][value]=200
924+
925+
#with index
926+
curl -X POST http://localhost:9292/api/v1/preference.json -d \
927+
&preferences[0][key]=foo \
928+
&preferences[1][key]=bar \
929+
&preferences[0][value]=100 \
930+
&preferences[1][value]=200
931+
```
932+
933+
#### Hash
934+
```sh
935+
curl -X POST http://localhost:9292/api/v1/preference.json -d \
936+
&preferences[key]=foo \
937+
&preferences[value]=100 \
938+
````
939+
915940
### Dependent Parameters
916941

917942
Suppose some of your parameters are only relevant if another parameter is given;

lib/grape.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ module Util
129129
autoload :InheritableSetting
130130
autoload :StrictHashConfiguration
131131
autoload :FileResponse
132+
autoload :HashParameter
132133
end
133134

134135
module DSL

lib/grape/dsl/parameters.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ module DSL
88
module Parameters
99
extend ActiveSupport::Concern
1010

11+
include Grape::Util::HashParameter
12+
1113
# Include reusable params rules among current.
1214
# You can define reusable params with helpers method.
1315
#
@@ -188,6 +190,7 @@ def declared_param?(param)
188190
# @api private
189191
def params(params)
190192
params = @parent.params(params) if @parent
193+
191194
if @element
192195
if params.is_a?(Array)
193196
params = params.flat_map { |el| el[@element] || {} }
@@ -197,6 +200,9 @@ def params(params)
197200
params = {}
198201
end
199202
end
203+
204+
params = params.values if params.is_a?(Hash) && deem_hash_array?(params)
205+
200206
params
201207
end
202208
end

lib/grape/util/hash_parameter.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
require 'active_support/concern'
2+
module Grape
3+
module Util
4+
module HashParameter
5+
extend ActiveSupport::Concern
6+
7+
def deem_hash_array?(hash)
8+
return false unless hash.is_a?(Hash) && hash.keys.any? { |key| integer_string?(key) }
9+
true
10+
end
11+
12+
def integer_string?(str)
13+
Integer(str)
14+
true
15+
rescue ArgumentError, TypeError
16+
false
17+
end
18+
end
19+
end
20+
end

lib/grape/validations/validators/base.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ module Validations
33
class Base
44
attr_reader :attrs
55

6+
include Grape::Util::HashParameter
7+
68
# Creates a new Validator from options specified
79
# by a +requires+ or +optional+ directive during
810
# parameter definition.

lib/grape/validations/validators/coerce.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ def valid_type?(val)
3636

3737
# Allow nil, to ignore when a parameter is absent
3838
return true if val.nil?
39-
40-
converter.value_coerced? val
39+
unless !type.is_a?(Types::VariantCollectionCoercer) && type == Array && val.is_a?(Hash) && deem_hash_array?(val)
40+
return converter.value_coerced? val
41+
end
42+
true
4143
end
4244

4345
def coerce_value(val)

spec/grape/validations/validators/default_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ def app
9999
expect(last_response.body).to eq({ array: [{ name: 'name', with_default: 'default' }, { name: 'name2', with_default: 'bar2' }] }.to_json)
100100
end
101101

102+
it 'sets default values for grouped arrays with index' do
103+
get('/array?array[0][name]=name&array[1][name]=name2&array[0][with_default]=bar1')
104+
expect(last_response.status).to eq(200)
105+
expect(last_response.body).to eq({ array: { 0 => { name: 'name', with_default: 'bar1' }, 1 => { name: 'name2', with_default: 'default' } } }.to_json)
106+
end
107+
102108
context 'optional group with defaults' do
103109
subject do
104110
Class.new(Grape::API) do

0 commit comments

Comments
 (0)