diff --git a/lib/validates_timeliness/extensions.rb b/lib/validates_timeliness/extensions.rb index cf865fc..f70e3c0 100644 --- a/lib/validates_timeliness/extensions.rb +++ b/lib/validates_timeliness/extensions.rb @@ -1,9 +1,14 @@ module ValidatesTimeliness module Extensions - autoload :DateTimeSelect, 'validates_timeliness/extensions/date_time_select' + autoload :DateTimeSelect, 'validates_timeliness/extensions/date_time_select' + autoload :MultiparameterParser, 'validates_timeliness/extensions/multiparameter_parser' end def self.enable_date_time_select_extension! ::ActionView::Helpers::InstanceTag.send(:include, ValidatesTimeliness::Extensions::DateTimeSelect) end + + def self.enable_multiparameter_parser! + ::ActiveRecord::Base.send(:include, ValidatesTimeliness::Extensions::MultiparameterParser) + end end diff --git a/lib/validates_timeliness/extensions/multiparameter_parser.rb b/lib/validates_timeliness/extensions/multiparameter_parser.rb new file mode 100644 index 0000000..8b39b76 --- /dev/null +++ b/lib/validates_timeliness/extensions/multiparameter_parser.rb @@ -0,0 +1,31 @@ +module ValidatesTimeliness + module Extensions + module MultiparameterParser + extend ActiveSupport::Concern + + included do + alias_method_chain :instantiate_time_object, :timeliness + end + + private + + # Stricter handling of date and time values from multiparameter + # assignment from the date/time select view helpers + # + def instantiate_time_object_with_timeliness(name, values) + unless Date.valid_civil?(*values[0..2]) + 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? + return value + end + + if self.class.send(:create_time_zone_conversion_attribute?, name, column_for_attribute(name)) + Time.zone.local(*values) + else + Time.time_with_datetime_fallback(@@default_timezone, *values) + end + end + + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e68dcf6..910eebb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -17,6 +17,7 @@ require 'validates_timeliness' ValidatesTimeliness.setup do |c| c.extend_classes = [ ActiveModel::Validations, ActiveRecord::Base ] c.enable_date_time_select_extension! + c.enable_multiparameter_parser! end Time.zone = 'Australia/Melbourne' diff --git a/spec/validates_timeliness/extensions/multiparameter_parser_spec.rb b/spec/validates_timeliness/extensions/multiparameter_parser_spec.rb new file mode 100644 index 0000000..bda2693 --- /dev/null +++ b/spec/validates_timeliness/extensions/multiparameter_parser_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe ValidatesTimeliness::Extensions::MultiparameterParser do + let(:employee) { Employee.new } + + it 'should return string value for invalid dates' do + instantiate_time_object('birth_date', [2000, 2, 31]).should == '2000-02-31' + end + + it 'should return string value for invalid datetimes' do + instantiate_time_object('birth_datetime', [2000, 2, 31, 12, 0, 0]).should == '2000-02-31 12:00:00' + end + + # This is giving an error in AR for undefined @@default_timezone. + # it 'should return Time value for valid datetimes' do + # instantiate_time_object('birth_datetime', [2000, 2, 28, 12, 0, 0]).should be_find_of(Time) + # end + + def instantiate_time_object(name, values) + employee.send(:instantiate_time_object, name, values) + end +end