aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorRafael Mendonça França <rafaelmfranca@gmail.com>2012-08-21 10:13:55 -0300
committerRafael Mendonça França <rafaelmfranca@gmail.com>2012-08-21 10:36:01 -0300
commit8905c1fb496641c3cdb7b3b816ae6d3d4b2c2b73 (patch)
tree058bfafd14c6284c699e3ee84adf017acdcc3641 /activerecord
parentfdf4eae506fa9895e831f569bed3c4aa6a999a22 (diff)
downloadrails-8905c1fb496641c3cdb7b3b816ae6d3d4b2c2b73.tar.gz
rails-8905c1fb496641c3cdb7b3b816ae6d3d4b2c2b73.tar.bz2
rails-8905c1fb496641c3cdb7b3b816ae6d3d4b2c2b73.zip
Merge pull request #6986 from kennyj/fix_6975
Fix #6975. Round usec when writing timestamp attribute. Conflicts: activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md5
-rw-r--r--activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb19
-rw-r--r--activerecord/test/cases/dirty_test.rb15
3 files changed, 34 insertions, 5 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 9c063e897c..6f81625429 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,5 +1,10 @@
## Rails 3.2.9 (unreleased)
+* Round usec when comparing timestamp attributes in the dirty tracking.
+ Fixes #6975.
+
+ *kennyj*
+
* Use inversed parent for first and last child of has_many association.
*Ravil Bayramgalin*
diff --git a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
index 7abe29c7d5..4c3d5eed4c 100644
--- a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
+++ b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
@@ -41,11 +41,14 @@ module ActiveRecord
unless time.acts_like?(:time)
time = time.is_a?(String) ? Time.zone.parse(time) : time.to_time rescue time
end
- time = time.in_time_zone rescue nil if time
- changed = read_attribute(:#{attr_name}) != time
- write_attribute(:#{attr_name}, original_time)
- #{attr_name}_will_change! if changed
- @attributes_cache["#{attr_name}"] = time
+ zoned_time = time && time.in_time_zone rescue nil
+ rounded_time = round_usec(zoned_time)
+ rounded_value = round_usec(read_attribute("#{attr_name}"))
+ if (rounded_value != rounded_time) || (!rounded_value && original_time)
+ write_attribute("#{attr_name}", original_time)
+ #{attr_name}_will_change!
+ @attributes_cache["#{attr_name}"] = zoned_time
+ end
end
EOV
generated_attribute_methods.module_eval(method_body, __FILE__, line)
@@ -59,6 +62,12 @@ module ActiveRecord
time_zone_aware_attributes && !self.skip_time_zone_conversion_for_attributes.include?(name.to_sym) && column.type.in?([:datetime, :timestamp])
end
end
+
+ private
+ def round_usec(value)
+ return unless value
+ value.change(:usec => 0)
+ end
end
end
end
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index 26afd203d2..3bd2e909d7 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -521,6 +521,21 @@ class DirtyTest < ActiveRecord::TestCase
assert !pirate.previous_changes.key?('created_on')
end
+ def test_setting_time_attributes_with_time_zone_field_to_same_time_should_not_be_marked_as_a_change
+ in_time_zone 'Paris' do
+ target = Class.new(ActiveRecord::Base)
+ target.table_name = 'pirates'
+
+ created_on = Time.now
+
+ pirate = target.create(:created_on => created_on)
+ pirate.reload # Here mysql truncate the usec value to 0
+
+ pirate.created_on = created_on
+ assert !pirate.created_on_changed?
+ end
+ end
+
private
def with_partial_updates(klass, on = true)
old = klass.partial_updates?