From ea7c9ec7be48c69672ec76a50edb536d913ee7ee Mon Sep 17 00:00:00 2001 From: Adam Meehan Date: Wed, 27 Apr 2011 07:37:26 +1000 Subject: [PATCH] Type caste to Date for date columns in AR after parsing string in attribute writer --- lib/validates_timeliness/attribute_methods.rb | 12 +++++--- lib/validates_timeliness/orm/active_record.rb | 12 ++++++++ .../attribute_methods_spec.rb | 5 ---- .../orm/active_record_spec.rb | 30 ++++++++++++++++--- spec/validates_timeliness/orm/mongoid_spec.rb | 24 +++++++++++---- 5 files changed, 65 insertions(+), 18 deletions(-) diff --git a/lib/validates_timeliness/attribute_methods.rb b/lib/validates_timeliness/attribute_methods.rb index 4777e57..064c796 100644 --- a/lib/validates_timeliness/attribute_methods.rb +++ b/lib/validates_timeliness/attribute_methods.rb @@ -31,14 +31,11 @@ module ValidatesTimeliness end def define_timeliness_write_method(attr_name) - type = timeliness_attribute_type(attr_name) - timezone_aware = timeliness_attribute_timezone_aware?(attr_name) - method_body, line = <<-EOV, __LINE__ + 1 def #{attr_name}=(value) @timeliness_cache ||= {} @timeliness_cache["#{attr_name}"] = value - #{ "value = Timeliness::Parser.parse(value, :#{type}, :zone => (:current if #{timezone_aware})) if value.is_a?(String)" if ValidatesTimeliness.use_plugin_parser } + #{ timeliness_type_cast_code(attr_name) if ValidatesTimeliness.use_plugin_parser } super end EOV @@ -54,6 +51,13 @@ module ValidatesTimeliness generated_timeliness_methods.module_eval(method_body, __FILE__, line) end + def timeliness_type_cast_code(attr_name) + type = timeliness_attribute_type(attr_name) + timezone_aware = timeliness_attribute_timezone_aware?(attr_name) + + "value = Timeliness::Parser.parse(value, :#{type}, :zone => (:current if #{timezone_aware})) if value.is_a?(String)" + end + def generated_timeliness_methods @generated_timeliness_methods ||= Module.new.tap { |m| include(m) } end diff --git a/lib/validates_timeliness/orm/active_record.rb b/lib/validates_timeliness/orm/active_record.rb index 5d8ccef..4029cc2 100644 --- a/lib/validates_timeliness/orm/active_record.rb +++ b/lib/validates_timeliness/orm/active_record.rb @@ -18,6 +18,18 @@ module ValidatesTimeliness def timeliness_attribute_type(attr_name) columns_hash[attr_name.to_s].type end + + def timeliness_type_cast_code(attr_name) + type = timeliness_attribute_type(attr_name) + timezone_aware = timeliness_attribute_timezone_aware?(attr_name) + + <<-END + if value.is_a?(String) + value = Timeliness::Parser.parse(value, :#{type}, :zone => (:current if #{timezone_aware})) + value = value.to_date if value && :#{type} == :date + end + END + end end module InstanceMethods diff --git a/spec/validates_timeliness/attribute_methods_spec.rb b/spec/validates_timeliness/attribute_methods_spec.rb index 02bdecc..e6864a4 100644 --- a/spec/validates_timeliness/attribute_methods_spec.rb +++ b/spec/validates_timeliness/attribute_methods_spec.rb @@ -60,11 +60,6 @@ describe ValidatesTimeliness::AttributeMethods do r.birth_date = '2010-01-01' end - it 'should parse string as current timezone' do - r = PersonWithParser.new - r.birth_datetime = '2010-01-01 12:00' - r.birth_datetime.zone == Time.zone.name - end end end diff --git a/spec/validates_timeliness/orm/active_record_spec.rb b/spec/validates_timeliness/orm/active_record_spec.rb index cb6a640..19ff24b 100644 --- a/spec/validates_timeliness/orm/active_record_spec.rb +++ b/spec/validates_timeliness/orm/active_record_spec.rb @@ -47,10 +47,32 @@ describe ValidatesTimeliness, 'ActiveRecord' do r.birth_date = '2010-01-01' end - it 'should parse string as current timezone' do - r = EmployeeWithParser.new - r.birth_datetime = '2010-06-01 12:00' - r.birth_datetime.utc_offset.should == 10.hours + context "for a date column" do + it 'should store a date value after parsing string' do + r = EmployeeWithParser.new + r.birth_date = '2010-01-01' + + r.birth_date.should be_kind_of(Date) + r.birth_date.should == Date.new(2010, 1, 1) + end + end + + context "for a datetime column" do + with_config(:default_timezone, 'Australia/Melbourne') + + it 'should parse string into Time value' do + r = EmployeeWithParser.new + r.birth_datetime = '2010-01-01 12:00' + + r.birth_datetime.should be_kind_of(Time) + end + + it 'should parse string as current timezone' do + r = EmployeeWithParser.new + r.birth_datetime = '2010-06-01 12:00' + + r.birth_datetime.utc_offset.should == Time.zone.utc_offset + end end end end diff --git a/spec/validates_timeliness/orm/mongoid_spec.rb b/spec/validates_timeliness/orm/mongoid_spec.rb index 33291cd..b8c34ce 100644 --- a/spec/validates_timeliness/orm/mongoid_spec.rb +++ b/spec/validates_timeliness/orm/mongoid_spec.rb @@ -60,10 +60,24 @@ describe ValidatesTimeliness, 'Mongoid' do r.publish_date = '2010-01-01' end - it 'should parse string into Time value' do - r = Article.new - r.publish_datetime = '2010-01-01 12:00' - r.publish_datetime.should == Time.utc(2010,1,1,12,0) + context "for a date column" do + it 'should store a date value after parsing string' do + r = Article.new + r.publish_date = '2010-01-01' + + r.publish_date.should be_kind_of(Date) + r.publish_date.should == Date.new(2010, 1, 1) + end + end + + context "for a datetime column" do + it 'should parse string into Time value' do + r = Article.new + r.publish_datetime = '2010-01-01 12:00' + + r.publish_datetime.should be_kind_of(Time) + r.publish_datetime.should == Time.utc(2010,1,1,12,0) + end end end end @@ -79,7 +93,7 @@ describe ValidatesTimeliness, 'Mongoid' do context "before_type_cast method" do it 'should not be defined if ORM does not support it' do - Article.new.should_not respond_to(:birth_datetime_before_type_cast) + Article.new.should_not respond_to(:publish_datetime_before_type_cast) end end end