Skip to content

Commit d1dfdcc

Browse files
authored
Feature: Allows procs with arity 1 to validate and use custom messages (#2333)
* refactor: validate_param! method - now allows a proc to validate and use custom messages - adds @proc_message instance variable - creates the skip_validation? method to pass rubocops cyclomatic error * Adds changelog entry * Adds PR # to the changelog * Properly formats the changelog line * Places the changelog line in the correct order * Adds default changelog message for future use * Edits the changelog with a better description * refactor: allows procs with an arity of 1 * Adds a test for when arity is > 1
1 parent 3b7901c commit d1dfdcc

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* [#2330](https://github.com/ruby-grape/grape/pull/2330): Use ActiveSupport inflector - [@ericproulx](https://github.com/ericproulx).
88
* [#2331](https://github.com/ruby-grape/grape/pull/2331): Memory optimization when running validators - [@ericproulx](https://github.com/ericproulx).
99
* [#2332](https://github.com/ruby-grape/grape/pull/2332): Use ActiveSupport configurable - [@ericproulx](https://github.com/ericproulx).
10+
* [#2333](https://github.com/ruby-grape/grape/pull/2333): Use custom messages in parameter validation with arity 1 - [@thedevjoao](https://github.com/TheDevJoao).
1011
* Your contribution here.
1112

1213
#### Fixes

lib/grape/validations/validators/values_validator.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def validate_param!(attr_name, params)
4343
unless check_values(param_array, attr_name)
4444

4545
raise validation_exception(attr_name, message(:values)) \
46-
if @proc && !param_array.all? { |param| @proc.call(param) }
46+
if @proc && !validate_proc(@proc, param_array)
4747
end
4848

4949
private
@@ -68,6 +68,17 @@ def check_excepts(param_array)
6868
param_array.none? { |param| excepts.include?(param) }
6969
end
7070

71+
def validate_proc(proc, param_array)
72+
case proc.arity
73+
when 0
74+
param_array.all? { |_param| proc.call }
75+
when 1
76+
param_array.all? { |param| proc.call(param) }
77+
else
78+
raise ArgumentError, 'proc arity must be 0 or 1'
79+
end
80+
end
81+
7182
def except_message
7283
options = instance_variable_get(:@option)
7384
options_key?(:except_message) ? options[:except_message] : message(:except_values)

spec/grape/validations/validators/values_spec.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ def add_except(except)
3030
def include?(value)
3131
values.include?(value)
3232
end
33+
34+
def even?(value)
35+
value.to_i.even?
36+
end
3337
end
3438
end
3539
end
@@ -241,6 +245,18 @@ def include?(value)
241245
end
242246
get '/proc/message'
243247

248+
params do
249+
requires :number, values: { value: ->(v) { ValuesModel.even? v }, message: 'must be even' }
250+
end
251+
get '/proc/custom_message' do
252+
{ message: 'success' }
253+
end
254+
255+
params do
256+
requires :input_one, :input_two, values: { value: ->(v1, v2) { v1 + v2 > 10 } }
257+
end
258+
get '/proc/arity2'
259+
244260
params do
245261
optional :name, type: String, values: %w[a b], allow_blank: true
246262
end
@@ -692,5 +708,26 @@ def app
692708
expect(last_response.status).to eq 400
693709
expect(last_response.body).to eq({ error: 'type failed check' }.to_json)
694710
end
711+
712+
context 'when proc has an arity of 1' do
713+
it 'accepts a valid value' do
714+
get '/proc/custom_message', number: 4
715+
expect(last_response.status).to eq 200
716+
expect(last_response.body).to eq({ message: 'success' }.to_json)
717+
end
718+
719+
it 'rejects an invalid value' do
720+
get '/proc/custom_message', number: 5
721+
expect(last_response.status).to eq 400
722+
expect(last_response.body).to eq({ error: 'number must be even' }.to_json)
723+
end
724+
end
725+
726+
context 'when arity is > 1' do
727+
it 'returns an error status code' do
728+
get '/proc/arity2', input_one: 2, input_two: 3
729+
expect(last_response.status).to eq 400
730+
end
731+
end
695732
end
696733
end

0 commit comments

Comments
 (0)