Class: DateValidator

Inherits:
ActiveModel::EachValidator
  • Object
show all
Defined in:
lib/validators/date_validator.rb

Instance Method Summary collapse

Instance Method Details

#date_for(record, value, option) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/validators/date_validator.rb', line 67

def date_for(record, value, option)
  date = case option
         when :today
           Date.today
         when :now
           Time.now + 60  # be lenient on now for server clocks
         when Time, Date, DateTime, ActiveSupport::TimeWithZone
           option
         when Proc
           option.call(record)
         else
           record.__send__(option) if record.respond_to?(option)
         end
  return unless date.present?
  date = date.to_date unless options[:time]
  if date.is_a?(Time)
    value = value.to_time
  elsif date.is_a?(Date)
    value = value.to_date
  end
  [date, value]
end

#validate_after_option(record, attribute, value, original_value) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/validators/date_validator.rb', line 30

def validate_after_option(record, attribute, value, original_value)
  date, value = date_for(record, value, options[:after])
  return true unless date.present?
  return true if value.present? && date.present? && (value && date && value >= date)

  after_message = ": #{original_value} is not a valid value."
  if options[:after] == :now || options[:after] == :today
    after_message << " Date cannot be in the past"
  elsif options[:after].respond_to?(:strftime)
    after_message << " Date cannot be before #{options[:after]}"
  elsif options[:after].is_a? Proc
    after_message << " Date cannot be before #{options[:after].call(record)}"
  elsif record.respond_to?(options[:after])
    after_message << " Date cannot be before #{options[:after]}"
  end
  after_message
end

#validate_before_option(record, attribute, value, original_value) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/validators/date_validator.rb', line 48

def validate_before_option(record, attribute, value, original_value)
  date, value = date_for(record, value, options[:before])
  return true unless date.present?
  return true if value.present? && date.present? && (value && date && value <= date)

    before_message = ": #{original_value} is not a valid value."
    if options[:before] == :now || options[:before] == :today
      before_message << " Date cannot be in the future" 
    elsif options[:before].respond_to?(:strftime)
      before_message << " Date cannot be after #{options[:before]}"
    elsif options[:before].is_a? Proc
      before_message << " Date cannot be after #{options[:before].call(record)}"
    elsif record.respond_to?(options[:before])
      before_message << " Date cannot be after #{options[:before]}"
    end
    before_message
end

#validate_each(record, attribute, value) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/validators/date_validator.rb', line 5

def validate_each(record, attribute, value)

  @error_hash = options[:error_level].present? ? record.send(options[:error_level]) : record.errors

  original_value = record.read_attribute_before_type_cast( attribute )
  # dont display date format error unless date could not be parsed
  if value.nil?
    # if blank date was given it's still not a format issue, still show message if desired
    return if original_value.blank? && options[:allow_blank]

    # display helpful date format validation message with original value
    message = options[:time] ?  ": #{original_value} is not a valid value. Value must be a date in YYYY-MM-DD or YYYY-MM-DD HH:MM:SS format." : ": #{original_value} is not a valid value. Value must be a date in YYYY-MM-DD."
    @error_hash.add(attribute, (options[:message] || message), rule_name: options[:rule_name])
  else
    # handle validation options on valid date instances
    return unless value.respond_to?(:strftime)
    if(options[:after] && (after_message = validate_after_option(record, attribute, value, original_value)) != true)
      @error_hash.add(attribute, (options[:after_message] || "#{after_message}."), rule_name: options[:rule_name])
    end
    if(options[:before] && (before_message = validate_before_option(record, attribute, value, original_value)) != true)
      @error_hash.add(attribute, (options[:before_message] || "#{before_message}."), rule_name: options[:rule_name])
    end
  end
end