Skip to content

Commit 10b15fe

Browse files
committed
Avoid coercing parameter with multiple types to an empty Array
If an optional parameter has multiple types (e.g. [File, String]) and a nil parameter is passed, Grape would previously coerce the value to an empty Array. This can break certain APIs that treat nil values differently from an empty Array. Closes #2018
1 parent 8deebb5 commit 10b15fe

File tree

3 files changed

+16
-1
lines changed

3 files changed

+16
-1
lines changed

CHANGELOG.md

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

33
#### Features
44
* Your contribution here.
5+
* [#2018](https://github.com/ruby-grape/grape/pull/2018): Avoid coercing parameter with multiple types to an empty Array - [@stanhu](https://github.com/stanhu).
56
* [#2015](https://github.com/ruby-grape/grape/pull/2014): Reduce MatchData allocation - [@ericproulx](https://github.com/ericproulx).
67
* [#2014](https://github.com/ruby-grape/grape/pull/2014): Reduce total allocated arrays - [@ericproulx](https://github.com/ericproulx).
78
* [#2011](https://github.com/ruby-grape/grape/pull/2011): Reduce total retained regexes - [@ericproulx](https://github.com/ericproulx).

lib/grape/validations/validators/coerce.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,10 @@ def coerce_value(val)
6868
# define default values for structures, the dry-types lib which is used
6969
# for coercion doesn't accept nil as a value, so it would fail
7070
if val.nil?
71-
return [] if type == Array || type.is_a?(Array)
71+
return [] if type == Array
7272
return Set.new if type == Set
7373
return {} if type == Hash
74+
return val if type.is_a?(Array)
7475
end
7576

7677
converter.call(val)

spec/grape/validations/validators/coerce_spec.rb

+13
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,19 @@ def self.parsed?(value)
647647
expect(last_response.body).to eq('String')
648648
end
649649

650+
it 'respects nil values' do
651+
subject.params do
652+
optional :a, types: [File, String]
653+
end
654+
subject.get '/' do
655+
params[:a].class.to_s
656+
end
657+
658+
get '/', a: nil
659+
expect(last_response.status).to eq(200)
660+
expect(last_response.body).to eq('NilClass')
661+
end
662+
650663
it 'fails when no coercion is possible' do
651664
subject.params do
652665
requires :a, types: [Boolean, Integer]

0 commit comments

Comments
 (0)