mirror of https://github.com/rails/rails
Add validate numericality in range
This commit is contained in:
parent
c28c800803
commit
2486e887de
|
@ -1,3 +1,7 @@
|
|||
* Add `in: range` parameter to `numericality` validator.
|
||||
|
||||
*Michal Papis*
|
||||
|
||||
* Add `locale` argument to `ActiveModel::Name#initialize` to be used to generate the `singular`,
|
||||
`plural`, `route_key` and `singular_route_key` values.
|
||||
|
||||
|
|
|
@ -32,5 +32,6 @@ en:
|
|||
less_than: "must be less than %{count}"
|
||||
less_than_or_equal_to: "must be less than or equal to %{count}"
|
||||
other_than: "must be other than %{count}"
|
||||
in: "must be in %{count}"
|
||||
odd: "must be odd"
|
||||
even: "must be even"
|
||||
|
|
|
@ -7,7 +7,7 @@ module ActiveModel
|
|||
class NumericalityValidator < EachValidator # :nodoc:
|
||||
CHECKS = { greater_than: :>, greater_than_or_equal_to: :>=,
|
||||
equal_to: :==, less_than: :<, less_than_or_equal_to: :<=,
|
||||
odd: :odd?, even: :even?, other_than: :!= }.freeze
|
||||
odd: :odd?, even: :even?, other_than: :!=, in: :in? }.freeze
|
||||
|
||||
RESERVED_OPTIONS = CHECKS.keys + [:only_integer]
|
||||
|
||||
|
@ -16,12 +16,17 @@ module ActiveModel
|
|||
HEXADECIMAL_REGEX = /\A[+-]?0[xX]/
|
||||
|
||||
def check_validity!
|
||||
keys = CHECKS.keys - [:odd, :even]
|
||||
keys = CHECKS.keys - [:odd, :even, :in]
|
||||
options.slice(*keys).each do |option, value|
|
||||
unless value.is_a?(Numeric) || value.is_a?(Proc) || value.is_a?(Symbol)
|
||||
raise ArgumentError, ":#{option} must be a number, a symbol or a proc"
|
||||
end
|
||||
end
|
||||
options.slice(:in).each do |option, value|
|
||||
unless value.is_a?(Range)
|
||||
raise ArgumentError, ":#{option} must be a range"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def validate_each(record, attr_name, value, precision: Float::DIG, scale: nil)
|
||||
|
@ -51,7 +56,7 @@ module ActiveModel
|
|||
option_value = record.send(option_value)
|
||||
end
|
||||
|
||||
option_value = parse_as_number(option_value, precision, scale)
|
||||
option_value = parse_as_number(option_value, precision, scale, option)
|
||||
|
||||
unless value.public_send(CHECKS[option], option_value)
|
||||
record.errors.add(attr_name, option, **filtered_options(value).merge!(count: option_value))
|
||||
|
@ -61,8 +66,10 @@ module ActiveModel
|
|||
end
|
||||
|
||||
private
|
||||
def parse_as_number(raw_value, precision, scale)
|
||||
if raw_value.is_a?(Float)
|
||||
def parse_as_number(raw_value, precision, scale, option = nil)
|
||||
if option == :in
|
||||
raw_value if raw_value.is_a?(Range)
|
||||
elsif raw_value.is_a?(Float)
|
||||
parse_float(raw_value, precision, scale)
|
||||
elsif raw_value.is_a?(Numeric)
|
||||
raw_value
|
||||
|
|
|
@ -7,6 +7,7 @@ require "models/person"
|
|||
|
||||
require "bigdecimal"
|
||||
require "active_support/core_ext/big_decimal"
|
||||
require "active_support/core_ext/object/inclusion"
|
||||
|
||||
class NumericalityValidationTest < ActiveModel::TestCase
|
||||
def teardown
|
||||
|
@ -206,6 +207,13 @@ class NumericalityValidationTest < ActiveModel::TestCase
|
|||
valid!([-1, 42])
|
||||
end
|
||||
|
||||
def test_validates_numericality_with_in
|
||||
Topic.validates_numericality_of :approved, in: 1..3
|
||||
|
||||
invalid!([0, 4])
|
||||
valid!([1, 2, 3])
|
||||
end
|
||||
|
||||
def test_validates_numericality_with_other_than_using_string_value
|
||||
Topic.validates_numericality_of :approved, other_than: 0
|
||||
|
||||
|
|
|
@ -528,6 +528,8 @@ constraints to acceptable values:
|
|||
less than or equal to %{count}"_.
|
||||
* `:other_than` - Specifies the value must be other than the supplied value.
|
||||
The default error message for this option is _"must be other than %{count}"_.
|
||||
* `:in` - Specifies the value must be in the supplied range.
|
||||
The default error message for this option is _"must be in %{count}"_.
|
||||
* `:odd` - Specifies the value must be an odd number if set to true. The
|
||||
default error message for this option is _"must be odd"_.
|
||||
* `:even` - Specifies the value must be an even number if set to true. The
|
||||
|
|
|
@ -993,6 +993,7 @@ So, for example, instead of the default error message `"cannot be blank"` you co
|
|||
| numericality | :less_than_or_equal_to | :less_than_or_equal_to | count |
|
||||
| numericality | :other_than | :other_than | count |
|
||||
| numericality | :only_integer | :not_an_integer | - |
|
||||
| numericality | :in | :in | count |
|
||||
| numericality | :odd | :odd | - |
|
||||
| numericality | :even | :even | - |
|
||||
|
||||
|
|
Loading…
Reference in New Issue