From e9fa4ca20a258d9291764e10fa6a9738a2e69507 Mon Sep 17 00:00:00 2001 From: Adam Meehan Date: Sun, 7 Dec 2008 11:07:39 +1100 Subject: [PATCH] fixed bug where accessor methods not properly generating due columns_hash lookup failing on method name as a symbol force value to time on write unless is a date attribute --- .../active_record/attribute_methods.rb | 11 +++++++---- spec/active_record/attribute_methods_spec.rb | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/validates_timeliness/active_record/attribute_methods.rb b/lib/validates_timeliness/active_record/attribute_methods.rb index b87201b..8eaf99d 100644 --- a/lib/validates_timeliness/active_record/attribute_methods.rb +++ b/lib/validates_timeliness/active_record/attribute_methods.rb @@ -65,11 +65,14 @@ module ValidatesTimeliness # implementation as it chains the write_attribute method which deletes # the attribute from the cache. def write_date_time_attribute(attr_name, value) - attr_name = attr_name.to_s column = column_for_attribute(attr_name) old = read_attribute(attr_name) if defined?(::ActiveRecord::Dirty) new = self.class.parse_date_time(value, column.type) + unless column.type == :date || new.nil? + new = new.to_time rescue new + end + if self.class.send(:create_time_zone_conversion_attribute?, attr_name, column) new = new.in_time_zone rescue nil end @@ -92,7 +95,7 @@ module ValidatesTimeliness if self.serialized_attributes[name] define_read_method_for_serialized_attribute(name) elsif create_time_zone_conversion_attribute?(name, column) - define_read_method_for_time_zone_conversion(name.to_sym) + define_read_method_for_time_zone_conversion(name) else define_read_method(name.to_sym, name, column) end @@ -100,7 +103,7 @@ module ValidatesTimeliness unless instance_method_already_implemented?("#{name}=") if [:date, :time, :datetime].include?(column.type) - define_write_method_for_dates_and_times(name.to_sym) + define_write_method_for_dates_and_times(name) else define_write_method(name.to_sym) end @@ -119,7 +122,7 @@ module ValidatesTimeliness write_date_time_attribute('#{attr_name}', value) end EOV - evaluate_attribute_method attr_name, method_body + evaluate_attribute_method attr_name, method_body, "#{attr_name}=" end # Define time attribute reader. If reloading then check if cached, diff --git a/spec/active_record/attribute_methods_spec.rb b/spec/active_record/attribute_methods_spec.rb index 52e7413..e13b102 100644 --- a/spec/active_record/attribute_methods_spec.rb +++ b/spec/active_record/attribute_methods_spec.rb @@ -8,6 +8,21 @@ describe ValidatesTimeliness::ActiveRecord::AttributeMethods do @person = Person.new end + it "should call write_date_time_attribute when date attribute assigned value" do + @person.should_receive(:write_date_time_attribute) + @person.birth_date = "2000-01-01" + end + + it "should call write_date_time_attribute when time attribute assigned value" do + @person.should_receive(:write_date_time_attribute) + @person.birth_time = "12:00" + end + + it "should call write_date_time_attribute when datetime attribute assigned value" do + @person.should_receive(:write_date_time_attribute) + @person.birth_date_and_time = "2000-01-01 12:00" + end + it "should call parser on write for datetime attribute" do @person.class.should_receive(:parse_date_time).once @person.birth_date_and_time = "2000-01-01 02:03:04"