Class: ActiveModel::Validations::DateValidator

Inherits:
EachValidator
  • Object
show all
Defined in:
lib/active_model/validations/date_validator.rb

Overview

Date Validator. Inherits from ActiveModel::EachValidator.

Responds to the regular validator API methods ‘#check_validity` and `#validate_each`.

Constant Summary collapse

CHECKS =

Implemented checks and their associated operators.

{ :after => :>, :after_or_equal_to => :>=,
:before => :<, :before_or_equal_to => :<=}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ DateValidator

Call ‘#initialize` on the superclass, adding a default `:allow_nil => false` option.



21
22
23
# File 'lib/active_model/validations/date_validator.rb', line 21

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

Instance Method Details

#check_validity!Object

Validates the arguments passed to the validator.

They must be either any kind of Time, a Proc, or a Symbol.



28
29
30
31
32
33
34
# File 'lib/active_model/validations/date_validator.rb', line 28

def check_validity!
  keys = CHECKS.keys
  options.slice(*keys).each do |option, value|
    next if is_time?(value) || value.is_a?(Proc) || value.is_a?(Symbol) || (defined?(ActiveSupport::TimeWithZone) and value.is_a? ActiveSupport::TimeWithZone)
    raise ArgumentError, ":#{option} must be a time, a date, a time_with_zone, a symbol or a proc"
  end
end

#validate_each(record, attr_name, value) ⇒ Object

The actual validator method. It is called when ActiveRecord iterates over all the validators.



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
# File 'lib/active_model/validations/date_validator.rb', line 38

def validate_each(record, attr_name, value)
  return if options[:allow_nil] && value.nil?

  unless value
    record.errors.add(attr_name, :not_a_date, options)
    return
  end
  
  options.slice(*CHECKS.keys).each do |option, option_value|
    option_value = option_value.call(record) if option_value.is_a?(Proc)
    option_value = record.send(option_value) if option_value.is_a?(Symbol)
 
    original_value = value
    original_option_value = option_value

    # To enable to_i conversion, these types must be converted to Datetimes
    if defined?(ActiveSupport::TimeWithZone)
      option_value = option_value.to_datetime if option_value.is_a?(ActiveSupport::TimeWithZone) 
      value = value.to_datetime if value.is_a?(ActiveSupport::TimeWithZone)  
    end

    if defined?(Date)
      option_value = option_value.to_datetime if option_value.is_a?(Date) 
      value = value.to_datetime if value.is_a?(Date)  
    end
   
    unless is_time?(option_value) && value.to_i.send(CHECKS[option], option_value.to_i)
      record.errors.add(attr_name, option, options.merge(:value => original_value, :date => original_option_value))
    end
  end
end