Skip to content

Commit

Permalink
Merge pull request #1325 from ngonzalez/fix-coerce-with-arrays
Browse files Browse the repository at this point in the history
Params: Fix coerce_with helper and Arrays types
  • Loading branch information
dblock committed Mar 16, 2016
2 parents f5d3ddc + 315f2d3 commit 21b58b1
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#### Fixes

* [#1325](https://github.com/ruby-grape/grape/pull/1325): Params: Fix coerce_with helper with Array types - [@ngonzalez](https://github.com/ngonzalez).

0.15.0 (3/8/2016)
=================

Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,15 @@ params do
end
```

Example of use of `coerce_with` with a lambda (a class with a `parse` method could also have been used)
It will parse a string and return an Array of Integers, matching the `Array[Integer]` `type`.

```ruby
params do
requires :values, type: Array[Integer], coerce_with: ->(val) { val.split(/\s+/).map(&:to_i) }
end
```

### Multipart File Parameters

Grape makes use of `Rack::Request`'s built-in support for multipart
Expand Down
2 changes: 2 additions & 0 deletions lib/grape/validations/types/custom_type_coercer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ def infer_type_check(type)
# Note that this will fail unless a method is also
# passed, or if the type also implements a parse() method.
type
elsif type.is_a?(Enumerable)
->(value) { value.all? { |item| item.is_a? type[0] } }
else
# By default, do a simple type check
->(value) { value.is_a? type }
Expand Down
51 changes: 51 additions & 0 deletions spec/grape/validations/validators/coerce_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,57 @@ class User
end

context 'using coerce_with' do
it 'parses parameters with Array type' do
subject.params do
requires :values, type: Array, coerce_with: ->(val) { val.split(/\s+/).map(&:to_i) }
end
subject.get '/ints' do
params[:values]
end

get '/ints', values: '1 2 3 4'
expect(last_response.status).to eq(200)
expect(JSON.parse(last_response.body)).to eq([1, 2, 3, 4])

get '/ints', values: 'a b c d'
expect(last_response.status).to eq(200)
expect(JSON.parse(last_response.body)).to eq([0, 0, 0, 0])
end

it 'parses parameters with Array[String] type' do
subject.params do
requires :values, type: Array[String], coerce_with: ->(val) { val.split(/\s+/).map(&:to_i) }
end
subject.get '/ints' do
params[:values]
end

get '/ints', values: '1 2 3 4'
expect(last_response.status).to eq(200)
expect(JSON.parse(last_response.body)).to eq(%w(1 2 3 4))

get '/ints', values: 'a b c d'
expect(last_response.status).to eq(200)
expect(JSON.parse(last_response.body)).to eq(%w(0 0 0 0))
end

it 'parses parameters with Array[Integer] type' do
subject.params do
requires :values, type: Array[Integer], coerce_with: ->(val) { val.split(/\s+/).map(&:to_i) }
end
subject.get '/ints' do
params[:values]
end

get '/ints', values: '1 2 3 4'
expect(last_response.status).to eq(200)
expect(JSON.parse(last_response.body)).to eq([1, 2, 3, 4])

get '/ints', values: 'a b c d'
expect(last_response.status).to eq(200)
expect(JSON.parse(last_response.body)).to eq([0, 0, 0, 0])
end

it 'uses parse where available' do
subject.params do
requires :ints, type: Array, coerce_with: JSON do
Expand Down

0 comments on commit 21b58b1

Please sign in to comment.