mirror of
https://github.com/ditkrg/validates_timeliness.git
synced 2026-01-23 06:16:44 +00:00
refactored restrictions validation into own method
added validates_*type methods for forcing the value type used when doing restriction validation
This commit is contained in:
parent
a27e4172a7
commit
d035de1d7c
@ -27,7 +27,7 @@ module ValidatesTimeliness
|
|||||||
begin
|
begin
|
||||||
time_array = ParseDate.parsedate(raw_value)
|
time_array = ParseDate.parsedate(raw_value)
|
||||||
|
|
||||||
# checks if date is valid which enforces number of days in a month unlike Time
|
# checks if date part is valid, enforcing days in a month unlike Time
|
||||||
Date.new(*time_array[0..2])
|
Date.new(*time_array[0..2])
|
||||||
|
|
||||||
# checks if time part is valid and returns object
|
# checks if time part is valid and returns object
|
||||||
@ -37,21 +37,12 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def timeliness_default_error_messages
|
|
||||||
defaults = ActiveRecord::Errors.default_error_messages.slice(:blank, :invalid_date, :before, :on_or_before, :after, :on_or_after)
|
|
||||||
returning({}) do |messages|
|
|
||||||
defaults.each {|k, v| messages["#{k}_message".to_sym] = v }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def validates_timeliness_of(*attr_names)
|
def validates_timeliness_of(*attr_names)
|
||||||
configuration = { :on => :save, :allow_nil => false, :allow_blank => false }
|
configuration = { :on => :save, :type => :time, :allow_nil => false, :allow_blank => false }
|
||||||
configuration.update(timeliness_default_error_messages)
|
configuration.update(timeliness_default_error_messages)
|
||||||
configuration.update(attr_names.extract_options!)
|
configuration.update(attr_names.extract_options!)
|
||||||
|
|
||||||
restriction_methods = {:before => '<', :after => '>', :on_or_before => '<=', :on_or_after => '>='}
|
# we need to check raw value for blank or nil in cases when an invalid value returns nil
|
||||||
|
|
||||||
# we need to check raw value for blank or nil to catch when invalid value returns nil
|
|
||||||
allow_nil = configuration.delete(:allow_nil)
|
allow_nil = configuration.delete(:allow_nil)
|
||||||
allow_blank = configuration.delete(:allow_blank)
|
allow_blank = configuration.delete(:allow_blank)
|
||||||
|
|
||||||
@ -69,52 +60,84 @@ module ValidatesTimeliness
|
|||||||
else
|
else
|
||||||
unless time = timeliness_date_time_parse(raw_value)
|
unless time = timeliness_date_time_parse(raw_value)
|
||||||
record.send("#{attr_name}=", nil)
|
record.send("#{attr_name}=", nil)
|
||||||
record.errors.add(attr_name, configuration[:invalid_date_message] % column.type)
|
record.errors.add(attr_name, configuration[:invalid_date_message] % configuration[:type])
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
conversion_method = column.type == :date ? :to_date : :to_time
|
validate_timeliness_restrictions(record, attr_name, time, configuration)
|
||||||
time = time.send(conversion_method)
|
|
||||||
|
|
||||||
restriction_methods.each do |option, method|
|
|
||||||
if restriction = configuration[option]
|
|
||||||
begin
|
|
||||||
compare = case restriction
|
|
||||||
when Date
|
|
||||||
restriction
|
|
||||||
when Time, DateTime
|
|
||||||
restriction.respond_to?(:in_time_zone) ? restriction.in_time_zone : restriction
|
|
||||||
when Symbol
|
|
||||||
record.send(restriction)
|
|
||||||
when Proc
|
|
||||||
restriction.call(record)
|
|
||||||
else
|
|
||||||
timeliness_date_time_parse(restriction)
|
|
||||||
end
|
|
||||||
|
|
||||||
next if compare.nil?
|
|
||||||
compare = compare.send(conversion_method) if compare
|
|
||||||
|
|
||||||
record.errors.add(attr_name, configuration["#{option}_message".to_sym] % compare) unless time.send(method, compare)
|
|
||||||
rescue
|
|
||||||
record.errors.add(attr_name, "restriction '#{option}' value was invalid")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
rescue
|
rescue
|
||||||
record.send("#{attr_name}=", nil)
|
record.send("#{attr_name}=", nil)
|
||||||
record.errors.add(attr_name, configuration[:invalid_date_message] % column.type)
|
record.errors.add(attr_name, configuration[:invalid_date_message] % configuration[:type])
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
alias validates_times validates_timeliness_of
|
# Use this validation to force validation of values as Time
|
||||||
alias validates_dates validates_timeliness_of
|
def validates_time(*attr_names)
|
||||||
alias validates_datetimes validates_timeliness_of
|
configuration = attr_names.extract_options!
|
||||||
end
|
configuration[:type] = :time
|
||||||
|
validates_timeliness_of(attr_names, configuration)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Use this validation to force validation of values as Date
|
||||||
|
def validates_date(*attr_names)
|
||||||
|
configuration = attr_names.extract_options!
|
||||||
|
configuration[:type] = :date
|
||||||
|
validates_timeliness_of(attr_names, configuration)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Use this validation to force validation of values as DateTime
|
||||||
|
def validates_datetime(*attr_names)
|
||||||
|
configuration = attr_names.extract_options!
|
||||||
|
configuration[:type] = :datetime
|
||||||
|
validates_timeliness_of(attr_names, configuration)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def validate_timeliness_restrictions(record, attr_name, value, configuration)
|
||||||
|
restriction_methods = {:before => '<', :after => '>', :on_or_before => '<=', :on_or_after => '>='}
|
||||||
|
|
||||||
|
conversion_method = "to_#{configuration[:type]}".to_sym
|
||||||
|
time = value.send(conversion_method)
|
||||||
|
|
||||||
|
restriction_methods.each do |option, method|
|
||||||
|
if restriction = configuration[option]
|
||||||
|
begin
|
||||||
|
compare = case restriction
|
||||||
|
when Date
|
||||||
|
restriction
|
||||||
|
when Time, DateTime
|
||||||
|
restriction.respond_to?(:in_time_zone) ? restriction.in_time_zone : restriction
|
||||||
|
when Symbol
|
||||||
|
record.send(restriction)
|
||||||
|
when Proc
|
||||||
|
restriction.call(record)
|
||||||
|
else
|
||||||
|
timeliness_date_time_parse(restriction)
|
||||||
|
end
|
||||||
|
|
||||||
|
next if compare.nil?
|
||||||
|
compare = compare.send(conversion_method) if compare
|
||||||
|
|
||||||
|
record.errors.add(attr_name, configuration["#{option}_message".to_sym] % compare) unless time.send(method, compare)
|
||||||
|
rescue
|
||||||
|
record.errors.add(attr_name, "restriction '#{option}' value was invalid")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def timeliness_default_error_messages
|
||||||
|
defaults = ActiveRecord::Errors.default_error_messages.slice(:blank, :invalid_date, :before, :on_or_before, :after, :on_or_after)
|
||||||
|
returning({}) do |messages|
|
||||||
|
defaults.each {|k, v| messages["#{k}_message".to_sym] = v }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -4,8 +4,8 @@ describe ValidatesTimeliness::Validations do
|
|||||||
describe "with no restrictions" do
|
describe "with no restrictions" do
|
||||||
before :all do
|
before :all do
|
||||||
class BasicValidation < Person
|
class BasicValidation < Person
|
||||||
validates_timeliness_of :birth_date_and_time, :allow_blank => true
|
validates_timeliness_of :birth_date_and_time, :allow_blank => true, :type => :datetime
|
||||||
validates_timeliness_of :birth_date, :allow_blank => true
|
validates_timeliness_of :birth_date, :allow_blank => true, :type => :date
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ describe ValidatesTimeliness::Validations do
|
|||||||
describe "with on_or_before and on_or_after restrictions" do
|
describe "with on_or_before and on_or_after restrictions" do
|
||||||
before :all do
|
before :all do
|
||||||
class DateOnOrBeforeAndAfter < Person
|
class DateOnOrBeforeAndAfter < Person
|
||||||
validates_timeliness_of :birth_date, :on_or_before => 1.day.from_now.to_date, :on_or_after => 1.day.ago.to_date
|
validates_timeliness_of :birth_date, :on_or_before => 1.day.from_now.to_date, :on_or_after => 1.day.ago.to_date, :type => :date
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user