aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib/active_model/validations
diff options
context:
space:
mode:
Diffstat (limited to 'activemodel/lib/active_model/validations')
-rw-r--r--activemodel/lib/active_model/validations/acceptance.rb5
-rw-r--r--activemodel/lib/active_model/validations/confirmation.rb4
-rw-r--r--activemodel/lib/active_model/validations/length.rb2
-rw-r--r--activemodel/lib/active_model/validations/numericality.rb31
4 files changed, 26 insertions, 16 deletions
diff --git a/activemodel/lib/active_model/validations/acceptance.rb b/activemodel/lib/active_model/validations/acceptance.rb
index ea3a6b52ab..6fd54270f2 100644
--- a/activemodel/lib/active_model/validations/acceptance.rb
+++ b/activemodel/lib/active_model/validations/acceptance.rb
@@ -54,8 +54,9 @@ module ActiveModel
def define_on(klass)
attr_readers = attributes.reject { |name| klass.attribute_method?(name) }
attr_writers = attributes.reject { |name| klass.attribute_method?("#{name}=") }
- klass.send(:attr_reader, *attr_readers)
- klass.send(:attr_writer, *attr_writers)
+ klass.define_attribute_methods
+ klass.attr_reader(*attr_readers)
+ klass.attr_writer(*attr_writers)
end
private
diff --git a/activemodel/lib/active_model/validations/confirmation.rb b/activemodel/lib/active_model/validations/confirmation.rb
index 1b5d5b09ab..b549755ba4 100644
--- a/activemodel/lib/active_model/validations/confirmation.rb
+++ b/activemodel/lib/active_model/validations/confirmation.rb
@@ -19,11 +19,11 @@ module ActiveModel
private
def setup!(klass)
- klass.send(:attr_reader, *attributes.map do |attribute|
+ klass.attr_reader(*attributes.map do |attribute|
:"#{attribute}_confirmation" unless klass.method_defined?(:"#{attribute}_confirmation")
end.compact)
- klass.send(:attr_writer, *attributes.map do |attribute|
+ klass.attr_writer(*attributes.map do |attribute|
:"#{attribute}_confirmation" unless klass.method_defined?(:"#{attribute}_confirmation=")
end.compact)
end
diff --git a/activemodel/lib/active_model/validations/length.rb b/activemodel/lib/active_model/validations/length.rb
index d6c80b2c5d..02759b4ccb 100644
--- a/activemodel/lib/active_model/validations/length.rb
+++ b/activemodel/lib/active_model/validations/length.rb
@@ -32,7 +32,7 @@ module ActiveModel
value = options[key]
unless (value.is_a?(Integer) && value >= 0) || value == Float::INFINITY || value.is_a?(Symbol) || value.is_a?(Proc)
- raise ArgumentError, ":#{key} must be a nonnegative Integer, Infinity, Symbol, or Proc"
+ raise ArgumentError, ":#{key} must be a non-negative Integer, Infinity, Symbol, or Proc"
end
end
end
diff --git a/activemodel/lib/active_model/validations/numericality.rb b/activemodel/lib/active_model/validations/numericality.rb
index b9ae42fd39..51e224d5cd 100644
--- a/activemodel/lib/active_model/validations/numericality.rb
+++ b/activemodel/lib/active_model/validations/numericality.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "bigdecimal/util"
+
module ActiveModel
module Validations
class NumericalityValidator < EachValidator # :nodoc:
@@ -9,6 +11,8 @@ module ActiveModel
RESERVED_OPTIONS = CHECKS.keys + [:only_integer]
+ INTEGER_REGEX = /\A[+-]?\d+\z/
+
def check_validity!
keys = CHECKS.keys - [:odd, :even]
options.slice(*keys).each do |option, value|
@@ -49,11 +53,7 @@ module ActiveModel
return
end
- if raw_value.is_a?(Numeric)
- value = raw_value
- else
- value = parse_raw_value_as_a_number(raw_value)
- end
+ value = parse_as_number(raw_value)
options.slice(*CHECKS.keys).each do |option, option_value|
case option
@@ -69,6 +69,8 @@ module ActiveModel
option_value = record.send(option_value)
end
+ option_value = parse_as_number(option_value)
+
unless value.send(CHECKS[option], option_value)
record.errors.add(attr_name, option, filtered_options(value).merge!(count: option_value))
end
@@ -79,22 +81,29 @@ module ActiveModel
private
def is_number?(raw_value)
- !parse_raw_value_as_a_number(raw_value).nil?
+ !parse_as_number(raw_value).nil?
rescue ArgumentError, TypeError
false
end
- def parse_raw_value_as_a_number(raw_value)
- return raw_value.to_i if is_integer?(raw_value)
- Kernel.Float(raw_value) unless is_hexadecimal_literal?(raw_value)
+ def parse_as_number(raw_value)
+ if raw_value.is_a?(Float)
+ raw_value.to_d
+ elsif raw_value.is_a?(Numeric)
+ raw_value
+ elsif is_integer?(raw_value)
+ raw_value.to_i
+ elsif !is_hexadecimal_literal?(raw_value)
+ Kernel.Float(raw_value).to_d
+ end
end
def is_integer?(raw_value)
- /\A[+-]?\d+\z/ === raw_value.to_s
+ INTEGER_REGEX.match?(raw_value.to_s)
end
def is_hexadecimal_literal?(raw_value)
- /\A0[xX]/ === raw_value
+ /\A0[xX]/.match?(raw_value.to_s)
end
def filtered_options(value)