mirror of
https://github.com/ditkrg/validates_timeliness.git
synced 2026-01-23 06:16:44 +00:00
81 lines
3.0 KiB
Ruby
81 lines
3.0 KiB
Ruby
module ValidatesTimeliness
|
|
module Extensions
|
|
module MultiparameterHandler
|
|
extend ActiveSupport::Concern
|
|
|
|
# Stricter handling of date and time values from multiparameter
|
|
# assignment from the date/time select view helpers
|
|
|
|
included do
|
|
alias_method_chain :instantiate_time_object, :timeliness
|
|
alias_method :execute_callstack_for_multiparameter_attributes, :execute_callstack_for_multiparameter_attributes_with_timeliness
|
|
alias_method :read_value_from_parameter, :read_value_from_parameter_with_timeliness
|
|
end
|
|
|
|
private
|
|
|
|
def invalid_multiparameter_date_or_time_as_string(values)
|
|
value = [values[0], *values[1..2].map {|s| s.to_s.rjust(2,"0")} ].join("-")
|
|
value += ' ' + values[3..5].map {|s| s.to_s.rjust(2, "0") }.join(":") unless values[3..5].empty?
|
|
value
|
|
end
|
|
|
|
def instantiate_time_object_with_timeliness(name, values)
|
|
validate_multiparameter_date_values(values) {
|
|
instantiate_time_object_without_timeliness(name, values)
|
|
}
|
|
end
|
|
|
|
def instantiate_date_object(name, values)
|
|
validate_multiparameter_date_values(values) {
|
|
Date.new(*values)
|
|
}
|
|
end
|
|
|
|
# Yield if date values are valid
|
|
def validate_multiparameter_date_values(values)
|
|
if values[0..2].all?{ |v| v.present? } && Date.valid_civil?(*values[0..2])
|
|
yield
|
|
else
|
|
invalid_multiparameter_date_or_time_as_string(values)
|
|
end
|
|
end
|
|
|
|
def read_value_from_parameter_with_timeliness(name, values_from_param)
|
|
klass = (self.class.reflect_on_aggregation(name.to_sym) || column_for_attribute(name)).klass
|
|
values = values_from_param.is_a?(Hash) ? values_from_param.to_a.sort_by(&:first).map(&:last) : values_from_param
|
|
|
|
if values.empty? || values.all?{ |v| v.nil? }
|
|
nil
|
|
elsif klass == Time
|
|
instantiate_time_object(name, values)
|
|
elsif klass == Date
|
|
instantiate_date_object(name, values)
|
|
else
|
|
if respond_to?(:read_other_parameter_value)
|
|
read_date_parameter_value(name, values_from_param)
|
|
else
|
|
klass.new(*values)
|
|
end
|
|
end
|
|
end
|
|
|
|
def execute_callstack_for_multiparameter_attributes_with_timeliness(callstack)
|
|
errors = []
|
|
callstack.each do |name, values_with_empty_parameters|
|
|
begin
|
|
send(name + "=", read_value_from_parameter(name, values_with_empty_parameters))
|
|
rescue => ex
|
|
values = values_with_empty_parameters.is_a?(Hash) ? values_with_empty_parameters.values : values_with_empty_parameters
|
|
errors << ActiveRecord::AttributeAssignmentError.new("error on assignment #{values.inspect} to #{name}", ex, name)
|
|
end
|
|
end
|
|
unless errors.empty?
|
|
raise ActiveRecord::MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|