Class: ActiveModel::Validations::NumericalityValidator

Inherits:
EachValidator show all
Defined in:
lib/active_model/validations/numericality.rb

Overview

:nodoc:

Constant Summary collapse

CHECKS =
{ greater_than: :>, greater_than_or_equal_to: :>=,
equal_to: :==, less_than: :<, less_than_or_equal_to: :<=,
odd: :odd?, even: :even?, other_than: :!= }.freeze
RESERVED_OPTIONS =
CHECKS.keys + [:only_integer]
INTEGER_REGEX =
/\A[+-]?\d+\z/
HEXADECIMAL_REGEX =
/\A[+-]?0[xX]/

Instance Attribute Summary

Attributes inherited from EachValidator

#attributes

Attributes inherited from ActiveModel::Validator

#options

Instance Method Summary collapse

Methods inherited from EachValidator

#initialize, #validate

Methods inherited from ActiveModel::Validator

#initialize, kind, #kind, #validate

Constructor Details

This class inherits a constructor from ActiveModel::EachValidator

Instance Method Details

#check_validity!Object

[View source]

18
19
20
21
22
23
24
25
# File 'lib/active_model/validations/numericality.rb', line 18

def check_validity!
  keys = CHECKS.keys - [:odd, :even]
  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
end

#validate_each(record, attr_name, value) ⇒ Object

[View source]

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/active_model/validations/numericality.rb', line 27

def validate_each(record, attr_name, value)
  came_from_user = :"#{attr_name}_came_from_user?"

  if record.respond_to?(came_from_user)
    if record.public_send(came_from_user)
      raw_value = record.read_attribute_before_type_cast(attr_name)
    elsif record.respond_to?(:read_attribute)
      raw_value = record.read_attribute(attr_name)
    end
  else
    before_type_cast = :"#{attr_name}_before_type_cast"
    if record.respond_to?(before_type_cast)
      raw_value = record.public_send(before_type_cast)
    end
  end
  raw_value ||= value

  if record_attribute_changed_in_place?(record, attr_name)
    raw_value = value
  end

  unless is_number?(raw_value)
    record.errors.add(attr_name, :not_a_number, filtered_options(raw_value))
    return
  end

  if allow_only_integer?(record) && !is_integer?(raw_value)
    record.errors.add(attr_name, :not_an_integer, filtered_options(raw_value))
    return
  end

  value = parse_as_number(raw_value)

  options.slice(*CHECKS.keys).each do |option, option_value|
    case option
    when :odd, :even
      unless value.to_i.send(CHECKS[option])
        record.errors.add(attr_name, option, filtered_options(value))
      end
    else
      case option_value
      when Proc
        option_value = option_value.call(record)
      when Symbol
        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
    end
  end
end