fixed restriction value conversion and added nil check

This commit is contained in:
Adam Meehan 2008-05-03 18:12:51 +10:00
parent cae3d8cb84
commit 9a8a82c699
2 changed files with 39 additions and 28 deletions

View File

@ -8,48 +8,56 @@ module ValidatesTimeliness
module ClassMethods module ClassMethods
def validates_timeliness_of(*attr_names) def validates_timeliness_of(*attr_names)
# possible options only_date only_time only_epoch configuration = { :on => :save, :allow_nil => false, :allow_blank => false }
configuration = { :on => :save, :allow_nil => false }
configuration.update(attr_names.extract_options!) configuration.update(attr_names.extract_options!)
restriction_methods = {:before => '<', :after => '>', :on_or_before => '<=', :on_or_after => '>='} restriction_methods = {:before => '<', :after => '>', :on_or_before => '<=', :on_or_after => '>='}
validates_each(attr_names, configuration) do |record, attr_name, value| # we need to check raw value for blank or nil to catch when invalid value returns nil
raw_value = record.send("#{attr_name}_before_type_cast") || value allow_nil = configuration.delete(:allow_nil)
allow_blank = configuration.delete(:allow_blank)
if raw_value.nil?
record.errors.add(attr_name, "cant' be blank") unless configuration[:allow_nil] validates_each(attr_names, configuration) do |record, attr_name, value|
next raw_value = record.send("#{attr_name}_before_type_cast")
end
next if (raw_value.nil? && allow_nil) || (raw_value.blank? && allow_blank)
record.errors.add(attr_name, "can't be blank") and next if raw_value.blank?
column = record.column_for_attribute(attr_name) column = record.column_for_attribute(attr_name)
begin begin
time = if raw_value.acts_like?(:time) time = if raw_value.acts_like?(:time) || raw_value.is_a?(Date)
raw_value raw_value
elsif raw_value.is_a?(Date)
raw_value.to_time
else else
time_array = ParseDate.parsedate(raw_value) time_array = ParseDate.parsedate(raw_value)
# checks if date is valid and enforces number of days in a month unlike Time # checks if date is valid which enforces number of days in a month unlike Time
date = Date.new(*time_array[0..2]) Date.new(*time_array[0..2])
# checks if time is valid as it will accept bad date values # checks if time is valid and return object
Time.mktime(*time_array) Time.mktime(*time_array)
end end
conversion_method = column.type == :date ? :to_date : :to_time
time = time.send(conversion_method)
restriction_methods.each do |option, method| restriction_methods.each do |option, method|
if restriction = configuration[option] if restriction = configuration[option]
compare = case restriction begin
when Time, Date, DateTime compare = case restriction
restriction.to_time when Date
when Symbol restriction
record.send(restriction).to_time when Time, DateTime
when Proc restriction.respond_to?(:in_time_zone) ? restriction.in_time_zone : restriction
restriction.call(record) when Symbol
end record.send(restriction)
when Proc
begin restriction.call(record)
end
next if compare.nil?
compare = compare.send(conversion_method) if compare
record.errors.add(attr_name, "must be #{option.to_s.humanize.downcase} #{compare}") unless time.send(method, compare) record.errors.add(attr_name, "must be #{option.to_s.humanize.downcase} #{compare}") unless time.send(method, compare)
rescue rescue
record.errors.add(attr_name, "restriction '#{option}' value was invalid") record.errors.add(attr_name, "restriction '#{option}' value was invalid")
@ -63,8 +71,11 @@ module ValidatesTimeliness
end end
end end
end end
alias validates_times validates_timeliness_of
alias validates_dates validates_timeliness_of
alias validates_datetimes validates_timeliness_of
end end
end end

View File

@ -9,7 +9,7 @@ describe ValidatesTimeliness::AttributeMethods do
it "should return string value for attribute_before_type_cast when written as string" do it "should return string value for attribute_before_type_cast when written as string" do
@person.birth_date_and_time = "1980-12-25 01:02:03" @person.birth_date_and_time = "1980-12-25 01:02:03"
@person.birth_date_and_time_before_type_cast.should == "1980-12-25 01:02:03" @person.birth_date_and_time_before_type_cast.should == "1980-12-25 01:02:03"
end end
it "should return Time object for attribute_before_type_cast when written as Time" do it "should return Time object for attribute_before_type_cast when written as Time" do