Skip to content

Commit 0c49453

Browse files
authored
Merge pull request #1947 from dnesteryuk/bugfix/1860
Careful check for empty params
2 parents 28d34ee + 1342559 commit 0c49453

File tree

5 files changed

+34
-14
lines changed

5 files changed

+34
-14
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#### Fixes
1616

17+
* [#1947](https://github.com/ruby-grape/grape/pull/1947): Careful check for empty params - [@dnesteryuk](https://github.com/dnesteryuk).
1718
* [#1931](https://github.com/ruby-grape/grape/pull/1946): Fixes issue when using namespaces in `Grape::API::Instance` mounted directly - [@myxoh](https://github.com/myxoh).
1819

1920
### 1.2.5 (2019/12/01)

lib/grape/validations/attributes_iterator.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ def do_each(params_to_process, parent_indicies = [], &block)
3131

3232
if @scope.type == Array
3333
next unless @original_params.is_a?(Array) # do not validate content of array if it isn't array
34-
inside_array = true
35-
end
36-
if inside_array
34+
3735
# fill current and parent scopes with correct array indicies
3836
parent_scope = @scope.parent
3937
parent_indicies.each do |parent_index|

lib/grape/validations/single_attribute_iterator.rb

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,20 @@ module Validations
55
class SingleAttributeIterator < AttributesIterator
66
private
77

8-
def yield_attributes(resource_params, attrs)
8+
def yield_attributes(val, attrs)
99
attrs.each do |attr_name|
10-
yield resource_params, attr_name
10+
yield val, attr_name, empty?(val)
1111
end
1212
end
13+
14+
# Primitives like Integers and Booleans don't respond to +empty?+.
15+
# It could be possible to use +blank?+ instead, but
16+
#
17+
# false.blank?
18+
# => true
19+
def empty?(val)
20+
val.respond_to?(:empty?) ? val.empty? : val.nil?
21+
end
1322
end
1423
end
1524
end

lib/grape/validations/validators/base.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ def validate!(params)
4242
# there may be more than one error per field
4343
array_errors = []
4444

45-
attributes.each do |resource_params, attr_name|
46-
next if !@scope.required? && resource_params.empty?
47-
next unless @scope.meets_dependency?(resource_params, params)
45+
attributes.each do |val, attr_name, empty_val|
46+
next if !@scope.required? && empty_val
47+
next unless @scope.meets_dependency?(val, params)
4848
begin
49-
if @required || resource_params.respond_to?(:key?) && resource_params.key?(attr_name)
50-
validate_param!(attr_name, resource_params)
49+
if @required || val.respond_to?(:key?) && val.key?(attr_name)
50+
validate_param!(attr_name, val)
5151
end
5252
rescue Grape::Exceptions::Validation => e
5353
array_errors << e

spec/grape/validations/single_attribute_iterator_spec.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
describe '#each' do
77
subject(:iterator) { described_class.new(validator, scope, params) }
88
let(:scope) { Grape::Validations::ParamsScope.new(api: Class.new(Grape::API)) }
9-
let(:validator) { double(attrs: %i[first second third]) }
9+
let(:validator) { double(attrs: %i[first second]) }
1010

1111
context 'when params is a hash' do
1212
let(:params) do
@@ -15,7 +15,7 @@
1515

1616
it 'yields params and every single attribute from the list' do
1717
expect { |b| iterator.each(&b) }
18-
.to yield_successive_args([params, :first], [params, :second], [params, :third])
18+
.to yield_successive_args([params, :first, false], [params, :second, false])
1919
end
2020
end
2121

@@ -26,10 +26,22 @@
2626

2727
it 'yields every single attribute from the list for each of the array elements' do
2828
expect { |b| iterator.each(&b) }.to yield_successive_args(
29-
[params[0], :first], [params[0], :second], [params[0], :third],
30-
[params[1], :first], [params[1], :second], [params[1], :third]
29+
[params[0], :first, false], [params[0], :second, false],
30+
[params[1], :first, false], [params[1], :second, false]
3131
)
3232
end
33+
34+
context 'empty values' do
35+
let(:params) { [{}, '', 10] }
36+
37+
it 'marks params with empty values' do
38+
expect { |b| iterator.each(&b) }.to yield_successive_args(
39+
[params[0], :first, true], [params[0], :second, true],
40+
[params[1], :first, true], [params[1], :second, true],
41+
[params[2], :first, false], [params[2], :second, false]
42+
)
43+
end
44+
end
3345
end
3446
end
3547
end

0 commit comments

Comments
 (0)