Class: ActiveModel::Validations::NumericalityValidator

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

Constant Summary

CHECKS =
{ :greater_than => :>, :greater_than_or_equal_to => :>=,
:equal_to => :==, :less_than => :<, :less_than_or_equal_to => :<=,
:odd => :odd?, :even => :even? }.freeze
RESERVED_OPTIONS =
CHECKS.keys + [:only_integer]

Instance Attribute Summary

Attributes inherited from EachValidator

#attributes

Attributes inherited from ActiveModel::Validator

#options

Instance Method Summary (collapse)

Methods inherited from EachValidator

#validate

Methods inherited from ActiveModel::Validator

kind, #kind, #validate

Constructor Details

- (NumericalityValidator) initialize(options)

Returns a new instance of NumericalityValidator



12
13
14
# File 'activemodel/lib/active_model/validations/numericality.rb', line 12

def initialize(options)
  super(options.reverse_merge(:only_integer => false, :allow_nil => false))
end

Instance Method Details

- (Object) check_validity!



16
17
18
19
20
21
22
# File 'activemodel/lib/active_model/validations/numericality.rb', line 16

def check_validity!
  keys = CHECKS.keys - [:odd, :even]
  options.slice(*keys).each do |option, value|
    next if 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

- (Object) validate_each(record, attr_name, value)



24
25
26
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
# File 'activemodel/lib/active_model/validations/numericality.rb', line 24

def validate_each(record, attr_name, value)
  before_type_cast = "#{attr_name}_before_type_cast"

  raw_value = record.send("#{attr_name}_before_type_cast") if record.respond_to?(before_type_cast.to_sym)
  raw_value ||= value

  return if options[:allow_nil] && raw_value.nil?

  unless value = parse_raw_value_as_a_number(raw_value)
    record.errors.add(attr_name, :not_a_number, filtered_options(raw_value))
    return
  end

  if options[:only_integer]
    unless value = parse_raw_value_as_an_integer(raw_value)
      record.errors.add(attr_name, :not_an_integer, filtered_options(raw_value))
      return
    end
  end

  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
      option_value = option_value.call(record) if option_value.is_a?(Proc)
      option_value = record.send(option_value) if option_value.is_a?(Symbol)

      unless value.send(CHECKS[option], option_value)
        record.errors.add(attr_name, option, filtered_options(value).merge(:count => option_value))
      end
    end
  end
end