mirror of
https://github.com/ditkrg/validates_timeliness.git
synced 2026-01-25 07:16:41 +00:00
first commit
This commit is contained in:
7
lib/validates_timeliness.rb
Normal file
7
lib/validates_timeliness.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
require 'validates_timeliness/base'
|
||||
require 'validates_timeliness/attribute_methods'
|
||||
require 'validates_timeliness/validations'
|
||||
|
||||
ActiveRecord::Base.send(:include, ValidatesTimeliness::Base)
|
||||
ActiveRecord::Base.send(:include, ValidatesTimeliness::AttributeMethods)
|
||||
ActiveRecord::Base.send(:include, ValidatesTimeliness::Validations)
|
||||
38
lib/validates_timeliness/attribute_methods.rb
Normal file
38
lib/validates_timeliness/attribute_methods.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
module ValidatesTimeliness
|
||||
module AttributeMethods
|
||||
|
||||
def self.included(base)
|
||||
base.extend ClassMethods
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def define_read_method_for_time_zone_conversion(attr_name)
|
||||
method_body = <<-EOV
|
||||
def #{attr_name}(reload = false)
|
||||
cached = @attributes_cache['#{attr_name}']
|
||||
return cached if cached && !reload
|
||||
time = read_attribute('#{attr_name}')
|
||||
unless time.acts_like?(:time)
|
||||
time = time.to_time(:local) rescue nil
|
||||
end
|
||||
@attributes_cache['#{attr_name}'] = time.acts_like?(:time) ? time.in_time_zone : time
|
||||
end
|
||||
EOV
|
||||
evaluate_attribute_method attr_name, method_body
|
||||
end
|
||||
|
||||
def define_write_method_for_time_zone_conversion(attr_name)
|
||||
method_body = <<-EOV
|
||||
def #{attr_name}=(time)
|
||||
if time
|
||||
time = time.in_time_zone if time.acts_like?(:time)
|
||||
end
|
||||
write_attribute(:#{attr_name}, time)
|
||||
end
|
||||
EOV
|
||||
evaluate_attribute_method attr_name, method_body, "#{attr_name}="
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
34
lib/validates_timeliness/base.rb
Normal file
34
lib/validates_timeliness/base.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
module ValidatesTimeliness
|
||||
module Base
|
||||
|
||||
def time_array_to_string(time_array)
|
||||
time_array.collect! {|i| i.to_s.rjust(2, '0') }
|
||||
time_array[0..2].join('-') + ' ' + time_array[3..5].join(':')
|
||||
end
|
||||
|
||||
def execute_callstack_for_multiparameter_attributes(callstack)
|
||||
errors = []
|
||||
callstack.each do |name, values|
|
||||
klass = (self.class.reflect_on_aggregation(name.to_sym) || column_for_attribute(name)).klass
|
||||
if values.empty?
|
||||
send(name + "=", nil)
|
||||
else
|
||||
begin
|
||||
value = if Time == klass || Date == klass
|
||||
time_array_to_string(values)
|
||||
else
|
||||
klass.new(*values)
|
||||
end
|
||||
send(name + "=", value)
|
||||
rescue => ex
|
||||
errors << AttributeAssignmentError.new("error on assignment #{values.inspect} to #{name}", ex, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
unless errors.empty?
|
||||
raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
48
lib/validates_timeliness/validations.rb
Normal file
48
lib/validates_timeliness/validations.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
module ValidatesTimeliness
|
||||
module Validations
|
||||
|
||||
def self.included(base)
|
||||
base.extend ClassMethods
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
||||
def validates_timeliness_of(*attr_names)
|
||||
# possible options only_date only_time only_epoch
|
||||
configuration = { :on => :save, :allow_nil => false }
|
||||
configuration.update(attr_names.extract_options!)
|
||||
|
||||
restriction_methods = {:before => '<', :after => '>', :on_or_before => '<=', :on_or_after => '>='}
|
||||
|
||||
validates_each(attr_names, configuration) do |record, attr_name, value|
|
||||
raw_value = record.send("#{attr_name}_before_type_cast") || value
|
||||
|
||||
next if raw_value.is_nil? and options[:allow_nil]
|
||||
|
||||
begin
|
||||
time_array = ParseDate.parsedate(raw_value)
|
||||
|
||||
# checks if date is valid and enforces number of days in a month unlike Time
|
||||
date = Date.new(*time_array[0..2])
|
||||
|
||||
# checks if time is valid as it will accept bad date values
|
||||
time = Time.mktime(*time_array)
|
||||
|
||||
restriction_methods.each do |option, method|
|
||||
if restriction = options[option]
|
||||
restriction = restriction.to_time
|
||||
record.errors.add(attr_name, "must be #{humanize(option)} #{restriction}") unless time.send(method, restriction)
|
||||
end
|
||||
end
|
||||
rescue
|
||||
record.errors.add(attr_name, "is not a valid time")
|
||||
next
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user