diff --git a/lib/validates_timeliness/multiparameter_attributes.rb b/lib/validates_timeliness/multiparameter_attributes.rb index 348e0c3..435689f 100644 --- a/lib/validates_timeliness/multiparameter_attributes.rb +++ b/lib/validates_timeliness/multiparameter_attributes.rb @@ -1,33 +1,46 @@ module ValidatesTimeliness module MultiparameterAttributes - def time_array_to_string(time_array) - "%04d-%02d-%02d %02d:%02d:%02d" % time_array + def self.included(base) + base.alias_method_chain :execute_callstack_for_multiparameter_attributes, :timeliness + end + + def time_array_to_string(time_array, type) + case type + when :time + "%02d:%02d:%02d" % time_array[3..5] + when :date + "%04d-%02d-%02d" % time_array[0..2] + when :datetime + "%04d-%02d-%02d %02d:%02d:%02d" % time_array + end end - # Overrides AR method to store multiparameter time and dates as - # ISO datetime string for later validation - def execute_callstack_for_multiparameter_attributes(callstack) + # Overrides AR method to store multiparameter time and dates as string + # allowing validation later. + def execute_callstack_for_multiparameter_attributes_with_timeliness(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 + column = column_for_attribute(name) begin - value = if Time == klass || Date == klass - time_array_to_string(values) + value = if [:date, :time, :datetime].include?(column.type) + time_array_to_string(values, column.type) else - klass.new(*values) + klass.new(*values) end - send("#{name}=", value) + send(name + "=", value) rescue => ex - errors << AttributeAssignmentError.new("error on assignment #{values.inspect} to #{name}", ex, name) + errors << ActiveRecord::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" + puts errors.inspect + raise ActiveRecord::MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes" end end diff --git a/spec/multiparameter_attributes_spec.rb b/spec/multiparameter_attributes_spec.rb index a866ac1..e4b0a25 100644 --- a/spec/multiparameter_attributes_spec.rb +++ b/spec/multiparameter_attributes_spec.rb @@ -1,37 +1,47 @@ require File.dirname(__FILE__) + '/spec_helper' describe ValidatesTimeliness::MultiparameterAttributes do - include ValidatesTimeliness::MultiparameterAttributes + def obj + @obj ||= Person.new + end - class AttributeAssignmentError; def initialize(*args); end; end - class MultiparameterAssignmentErrors; def initialize(*args); end; end - - before do - self.class.stub!(:reflect_on_aggregation).and_return(nil) - end - - it "should convert time array into string" do - time_string = time_array_to_string([2000,2,1,9,10,11]) + it "should convert array for datetime type into datetime string" do + time_string = obj.time_array_to_string([2000,2,1,9,10,11], :datetime) time_string.should == "2000-02-01 09:10:11" end - describe "execute_callstack_for_multiparameter_attributes" do - before do - @date_array = [2000,2,1,9,10,11] - end + it "should convert array for date type into date string" do + time_string = obj.time_array_to_string([2000,2,1,0,0,0], :date) + time_string.should == "2000-02-01" + end - it "should store time string for a Time class column" do - self.stub!(:column_for_attribute).and_return( mock('Column', :klass => Time) ) - self.should_receive(:birth_date_and_time=).once.with("2000-02-01 09:10:11") - callstack = {'birth_date_and_time' => @date_array} - execute_callstack_for_multiparameter_attributes(callstack) + it "should convert array for time type into time string" do + time_string = obj.time_array_to_string([2000,1,1,9,10,11], :time) + time_string.should == "09:10:11" + end + + describe "execute_callstack_for_multiparameter_attributes" do + before do + @callstack = { + 'birth_date_and_time' => [2000,2,1,9,10,11], + 'birth_date' => [2000,2,1,9,10,11], + 'birth_time' => [2000,2,1,9,10,11] + } + end + + it "should store datetime string for datetime column" do + obj.should_receive(:birth_date_and_time=).once.with("2000-02-01 09:10:11") + obj.send(:execute_callstack_for_multiparameter_attributes, @callstack) end - it "should store time string for a Date class column" do - self.stub!(:column_for_attribute).and_return( mock('Column', :klass => Date) ) - self.should_receive(:birth_date=).once.with("2000-02-01 09:10:11") - callstack = {'birth_date' => @date_array} - execute_callstack_for_multiparameter_attributes(callstack) + it "should store date string for a date column" do + obj.should_receive(:birth_date=).once.with("2000-02-01") + obj.send(:execute_callstack_for_multiparameter_attributes, @callstack) + end + + it "should store time string for a time column" do + obj.should_receive(:birth_time=).once.with("09:10:11") + obj.send(:execute_callstack_for_multiparameter_attributes, @callstack) end end