mirror of
https://github.com/ditkrg/validates_timeliness.git
synced 2026-01-25 07:16:41 +00:00
more refactoring of validator
fixed bug when Date is restriction value for a datetime attribute so its cast to time in default timezone
This commit is contained in:
parent
c224db7af8
commit
0c5cc1a536
@ -12,11 +12,11 @@ module Spec
|
|||||||
|
|
||||||
def initialize(attribute, options)
|
def initialize(attribute, options)
|
||||||
@expected, @options = attribute, options
|
@expected, @options = attribute, options
|
||||||
|
@validator = ValidatesTimeliness::Validator.new(options)
|
||||||
compile_error_messages
|
compile_error_messages
|
||||||
end
|
end
|
||||||
|
|
||||||
def compile_error_messages
|
def compile_error_messages
|
||||||
validator = ValidatesTimeliness::Validator.new(options)
|
|
||||||
messages = validator.send(:error_messages)
|
messages = validator.send(:error_messages)
|
||||||
@messages = messages.inject({}) {|h, (k, v)| h[k] = v.gsub(/ (\%s|\{\{\w*\}\})/, ''); h }
|
@messages = messages.inject({}) {|h, (k, v)| h[k] = v.gsub(/ (\%s|\{\{\w*\}\})/, ''); h }
|
||||||
end
|
end
|
||||||
@ -52,7 +52,7 @@ module Spec
|
|||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
attr_reader :actual, :expected, :record, :options, :messages, :last_failure
|
attr_reader :actual, :expected, :record, :options, :messages, :last_failure, :validator
|
||||||
|
|
||||||
def test_option(option, modifier, settings={})
|
def test_option(option, modifier, settings={})
|
||||||
settings.reverse_merge!(:modify_on => :valid)
|
settings.reverse_merge!(:modify_on => :valid)
|
||||||
@ -71,8 +71,7 @@ module Spec
|
|||||||
|
|
||||||
def parse_and_cast(value)
|
def parse_and_cast(value)
|
||||||
value = ValidatesTimeliness::Validator.send(:restriction_value, value, record, options[:type])
|
value = ValidatesTimeliness::Validator.send(:restriction_value, value, record, options[:type])
|
||||||
cast_method = ValidatesTimeliness::Validator.send(:restriction_type_cast_method, options[:type])
|
validator.send(:type_cast_value, value)
|
||||||
value.send(cast_method) rescue nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def error_matching(value, match)
|
def error_matching(value, match)
|
||||||
|
|||||||
@ -56,8 +56,7 @@ module ValidatesTimeliness
|
|||||||
configuration.delete(:allow_nil)
|
configuration.delete(:allow_nil)
|
||||||
configuration.delete(:allow_blank)
|
configuration.delete(:allow_blank)
|
||||||
validates_each(attr_names, configuration) do |record, attr_name, value|
|
validates_each(attr_names, configuration) do |record, attr_name, value|
|
||||||
raw_value = record.send("#{attr_name}_before_type_cast")
|
validator.call(record, attr_name)
|
||||||
validator.call(record, attr_name, raw_value)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ module ValidatesTimeliness
|
|||||||
# The validity of values can be restricted to be before or after certain dates
|
# The validity of values can be restricted to be before or after certain dates
|
||||||
# or times.
|
# or times.
|
||||||
class Validator
|
class Validator
|
||||||
attr_reader :configuration, :type, :messages
|
attr_reader :configuration, :type
|
||||||
|
|
||||||
def initialize(configuration)
|
def initialize(configuration)
|
||||||
defaults = { :on => :save, :type => :datetime, :allow_nil => false, :allow_blank => false }
|
defaults = { :on => :save, :type => :datetime, :allow_nil => false, :allow_blank => false }
|
||||||
@ -14,20 +14,25 @@ module ValidatesTimeliness
|
|||||||
|
|
||||||
# The main validation method which can be used directly or called through
|
# The main validation method which can be used directly or called through
|
||||||
# the other specific type validation methods.
|
# the other specific type validation methods.
|
||||||
def call(record, attr_name, value)
|
def call(record, attr_name)
|
||||||
return if (value.nil? && configuration[:allow_nil]) || (value.blank? && configuration[:allow_blank])
|
value = record.send(attr_name)
|
||||||
|
raw_value = raw_value(record, attr_name)
|
||||||
|
|
||||||
add_error(record, attr_name, :blank) and return if value.blank?
|
return if (raw_value.nil? && configuration[:allow_nil]) || (raw_value.blank? && configuration[:allow_blank])
|
||||||
|
|
||||||
time = record.class.parse_date_time(value, type)
|
add_error(record, attr_name, :blank) and return if raw_value.blank?
|
||||||
unless time
|
|
||||||
add_error(record, attr_name, "invalid_#{type}".to_sym) and return
|
add_error(record, attr_name, "invalid_#{type}".to_sym) and return unless value
|
||||||
end
|
|
||||||
validate_restrictions(record, attr_name, time)
|
validate_restrictions(record, attr_name, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def raw_value(record, attr_name)
|
||||||
|
record.send("#{attr_name}_before_type_cast")
|
||||||
|
end
|
||||||
|
|
||||||
# Validate value against the temporal restrictions. Restriction values
|
# Validate value against the temporal restrictions. Restriction values
|
||||||
# maybe of mixed type, so they are evaluated as a common type, which may
|
# maybe of mixed type, so they are evaluated as a common type, which may
|
||||||
# require conversion. The type used is defined by validation type.
|
# require conversion. The type used is defined by validation type.
|
||||||
@ -38,14 +43,14 @@ module ValidatesTimeliness
|
|||||||
|
|
||||||
display = ValidatesTimeliness.error_value_formats[type]
|
display = ValidatesTimeliness.error_value_formats[type]
|
||||||
|
|
||||||
value = value.send(type_cast_method)
|
value = type_cast_value(value)
|
||||||
|
|
||||||
restriction_methods.each do |option, method|
|
restriction_methods.each do |option, method|
|
||||||
next unless restriction = configuration[option]
|
next unless restriction = configuration[option]
|
||||||
begin
|
begin
|
||||||
compare = self.class.restriction_value(restriction, record, type)
|
compare = self.class.restriction_value(restriction, record, type)
|
||||||
next if compare.nil?
|
next if compare.nil?
|
||||||
compare = compare.send(type_cast_method)
|
compare = type_cast_value(compare)
|
||||||
|
|
||||||
unless value.send(method, compare)
|
unless value.send(method, compare)
|
||||||
add_error(record, attr_name, option, :restriction => compare.strftime(display))
|
add_error(record, attr_name, option, :restriction => compare.strftime(display))
|
||||||
@ -64,6 +69,7 @@ module ValidatesTimeliness
|
|||||||
message = message % interpolate.values unless interpolate.empty?
|
message = message % interpolate.values unless interpolate.empty?
|
||||||
record.errors.add(attr_name, message)
|
record.errors.add(attr_name, message)
|
||||||
else
|
else
|
||||||
|
# use i18n support in AR for message or us custom message passed to validation method
|
||||||
custom = custom_error_messages[message]
|
custom = custom_error_messages[message]
|
||||||
record.errors.add(attr_name, custom || message, interpolate)
|
record.errors.add(attr_name, custom || message, interpolate)
|
||||||
end
|
end
|
||||||
@ -100,5 +106,22 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def type_cast_value(value)
|
||||||
|
case type
|
||||||
|
when :time
|
||||||
|
value.to_dummy_time
|
||||||
|
when :date
|
||||||
|
value.to_date
|
||||||
|
when :datetime
|
||||||
|
if value.is_a?(DateTime) || value.is_a?(Time)
|
||||||
|
value.to_time
|
||||||
|
else
|
||||||
|
value.to_time(ValidatesTimelines.default_timezone)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user