Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add length validator #2437

Merged
merged 9 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
* [#2436](/~https://github.com/ruby-grape/grape/pull/2436): Update coverallsapp github-action - [@ericproulx](/~https://github.com/ericproulx).
* [#2434](/~https://github.com/ruby-grape/grape/pull/2434): Implement nested `with` support in parameter dsl - [@numbata](/~https://github.com/numbata).
* [#2438](/~https://github.com/ruby-grape/grape/pull/2438): Fix some Rack::Lint - [@ericproulx](/~https://github.com/ericproulx).
* [#2437](/~https://github.com/ruby-grape/grape/pull/2437): Add length validator - [@dhruvCW](/~https://github.com/dhruvCW).
* Your contribution here.

#### Fixes
Expand Down
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
- [values](#values)
- [except_values](#except_values)
- [same_as](#same_as)
- [length](#length)
- [regexp](#regexp)
- [mutually_exclusive](#mutually_exclusive)
- [exactly_one_of](#exactly_one_of)
Expand All @@ -69,6 +70,7 @@
- [Custom Validation messages](#custom-validation-messages)
- [presence, allow_blank, values, regexp](#presence-allow_blank-values-regexp)
- [same_as](#same_as-1)
- [length](#length-1)
- [all_or_none_of](#all_or_none_of-1)
- [mutually_exclusive](#mutually_exclusive-1)
- [exactly_one_of](#exactly_one_of-1)
Expand Down Expand Up @@ -1709,6 +1711,19 @@ params do
end
```

#### `length`

Parameters of type `String` or `Array` can be restricted to have a specific length or size with the `:length` option.

The validator accepts `:min` or `:max` or both options to validate that the value of the parameter is within the given limits.

```ruby
params do
requires :str, type: String, length: { min: 3 }
requires :list, type: [Integer], length: { min: 3, max: 5 }
end
```

#### `regexp`

Parameters can be restricted to match a specific regular expression with the `:regexp` option. If the value does not match the regular expression an error will be returned. Note that this is true for both `requires` and `optional` parameters.
Expand Down Expand Up @@ -2026,6 +2041,15 @@ params do
end
```

#### `length`

```ruby
params do
requires :str, length: { min: 5, message: 'str is expected to be atleast 5 characters long' }
requires :list, length: { min: 2, max: 3, message: 'list is expected to have between 2 and 3 elements' }
end
```

#### `all_or_none_of`

```ruby
Expand Down
3 changes: 3 additions & 0 deletions lib/grape/locale/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ en:
values: 'does not have a valid value'
except_values: 'has a value not allowed'
same_as: 'is not the same as %{parameter}'
length: 'is expected to have length within %{min} and %{max}'
length_min: 'is expected to have length greater than or equal to %{min}'
length_max: 'is expected to have length less than or equal to %{max}'
missing_vendor_option:
problem: 'missing :vendor option'
summary: 'when version using header, you must specify :vendor option'
Expand Down
3 changes: 3 additions & 0 deletions lib/grape/validations/attributes_doc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ def extract_details(validations)
details[:documentation] = documentation if documentation

details[:default] = validations[:default] if validations.key?(:default)

details[:min_length] = validations[:length][:min] if validations.key?(:length) && validations[:length].key?(:min)
dhruvCW marked this conversation as resolved.
Show resolved Hide resolved
details[:max_length] = validations[:length][:max] if validations.key?(:length) && validations[:length].key?(:max)
end

def document(attrs)
Expand Down
43 changes: 43 additions & 0 deletions lib/grape/validations/validators/length_validator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

module Grape
module Validations
module Validators
class LengthValidator < Base
def initialize(attrs, options, required, scope, **opts)
@min = options[:min]
@max = options[:max]

super

raise ArgumentError, 'min must be an integer greater than or equal to zero' if !@min.nil? && (!@min.is_a?(Integer) || @min.negative?)
raise ArgumentError, 'max must be an integer greater than or equal to zero' if !@max.nil? && (!@max.is_a?(Integer) || @max.negative?)
raise ArgumentError, "min #{@min} cannot be greater than max #{@max}" if !@min.nil? && !@max.nil? && @min > @max
dhruvCW marked this conversation as resolved.
Show resolved Hide resolved
end

def validate_param!(attr_name, params)
param = params[attr_name]
param = param.compact if param.respond_to?(:compact)

raise ArgumentError, "parameter #{param} has an unsupported type. Only strings & arrays are supported" unless params.is_a?(String) || param.is_a?(Array)
dhruvCW marked this conversation as resolved.
Show resolved Hide resolved

return unless (!@min.nil? && param.length < @min) || (!@max.nil? && param.length > @max)

raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: build_message)
end

def build_message
if options_key?(:message)
@option[:message]
elsif @min && @max
format I18n.t(:length, scope: 'grape.errors.messages'), min: @min, max: @max
elsif @min
format I18n.t(:length_min, scope: 'grape.errors.messages'), min: @min
else
format I18n.t(:length_max, scope: 'grape.errors.messages'), max: @max
end
end
end
end
end
end
7 changes: 5 additions & 2 deletions spec/grape/validations/attributes_doc_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
presence: true,
desc: 'Age of...',
documentation: 'Age is...',
default: 1
default: 1,
length: { min: 1, max: 13 }
}
end

Expand Down Expand Up @@ -77,7 +78,9 @@
documentation: validations[:documentation],
default: validations[:default],
type: 'Integer',
values: valid_values
values: valid_values,
min_length: validations[:length][:min],
max_length: validations[:length][:max]
}
end

Expand Down
Loading