Skip to content

Instantly share code, notes, and snippets.

@MattHall
Created July 13, 2010 13:59
Show Gist options
  • Save MattHall/473903 to your computer and use it in GitHub Desktop.
Save MattHall/473903 to your computer and use it in GitHub Desktop.
module MultiparameterHack
def self.included klass
klass.class_eval do
@date_error_on_attribute = nil
def validate
errors.add_to_base "Invalid Date #{@date_error_on_attribute}" if @date_error_on_attribute
end
undef :execute_callstack_for_multiparameter_attributes
def execute_callstack_for_multiparameter_attributes(callstack)
errors = []
callstack.each do |name, values_with_empty_parameters|
begin
klass = (self.class.reflect_on_aggregation(name.to_sym) || column_for_attribute(name)).klass
# in order to allow a date to be set without a year, we must keep the empty values.
# Otherwise, we wouldn't be able to distinguish it from a date with an empty day.
values = values_with_empty_parameters.reject(&:nil?)
if values.empty?
send(name + "=", nil)
else
value = if Time == klass
instantiate_time_object(name, values)
elsif Date == klass
begin
values = values_with_empty_parameters.collect do |v| v.nil? ? 1 : v end
Date.new(*values)
rescue ArgumentError => ex # if Date.new raises an exception on an invalid date
instantiate_time_object(name, values).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates
end
else
klass.new(*values)
end
send(name + "=", value)
end
rescue => ex
errors << ActiveRecord::AttributeAssignmentError.new("error on assignment #{values.inspect} to #{name}", ex, name)
if self.errors.empty?
@date_error_on_attribute = name
end
end
end
end
end
end
end
ActiveRecord::Base.send(:include, MultiparameterHack)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment