mirror of
https://github.com/github/rails.git
synced 2026-01-09 14:48:01 -05:00
Fix handling of dirty time zone aware attributes
Previously, when `time_zone_aware_attributes` were enabled, after
changing a datetime or timestamp attribute and then changing it back
to the original value, `changed_attributes` still tracked the
attribute as changed. This caused `[attribute]_changed?` and
`changed?` methods to return true incorrectly.
Example:
in_time_zone 'Paris' do
order = Order.new
original_time = Time.local(2012, 10, 10)
order.shipped_at = original_time
order.save
order.changed? # => false
# changing value
order.shipped_at = Time.local(2013, 1, 1)
order.changed? # => true
# reverting to original value
order.shipped_at = original_time
order.changed? # => false, used to return true
end
(cherry picked from commit bc982cbcb34129ea2cfe8aa1f8e0b40e444e68db)
Conflicts:
activerecord/CHANGELOG.md
activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
Backport of #9073
Fixes #8898
This commit is contained in:
committed by
Andrew White
parent
f7c8457453
commit
3c5f631caa
@@ -1,5 +1,36 @@
|
||||
## unreleased ##
|
||||
|
||||
* Fix handling of dirty time zone aware attributes
|
||||
|
||||
Previously, when `time_zone_aware_attributes` were enabled, after
|
||||
changing a datetime or timestamp attribute and then changing it back
|
||||
to the original value, `changed_attributes` still tracked the
|
||||
attribute as changed. This caused `[attribute]_changed?` and
|
||||
`changed?` methods to return true incorrectly.
|
||||
|
||||
Example:
|
||||
|
||||
in_time_zone 'Paris' do
|
||||
order = Order.new
|
||||
original_time = Time.local(2012, 10, 10)
|
||||
order.shipped_at = original_time
|
||||
order.save
|
||||
order.changed? # => false
|
||||
|
||||
# changing value
|
||||
order.shipped_at = Time.local(2013, 1, 1)
|
||||
order.changed? # => true
|
||||
|
||||
# reverting to original value
|
||||
order.shipped_at = original_time
|
||||
order.changed? # => false, used to return true
|
||||
end
|
||||
|
||||
Backport of #9073
|
||||
Fixes #8898
|
||||
|
||||
*Lilibeth De La Cruz*
|
||||
|
||||
* Fix counter cache columns not updated when replacing `has_many :through`
|
||||
associations.
|
||||
Backport #8400.
|
||||
|
||||
@@ -43,9 +43,9 @@ module ActiveRecord
|
||||
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
|
||||
previous_time = attribute_changed?("#{attr_name}") ? changed_attributes["#{attr_name}"] : read_attribute(:#{attr_name})
|
||||
write_attribute(:#{attr_name}, original_time)
|
||||
#{attr_name}_will_change! if changed
|
||||
#{attr_name}_will_change! if previous_time != time
|
||||
@attributes_cache["#{attr_name}"] = time
|
||||
end
|
||||
EOV
|
||||
|
||||
@@ -76,6 +76,8 @@ class DirtyTest < ActiveRecord::TestCase
|
||||
assert pirate.created_on_changed?
|
||||
assert_kind_of ActiveSupport::TimeWithZone, pirate.created_on_was
|
||||
assert_equal old_created_on, pirate.created_on_was
|
||||
pirate.created_on = old_created_on
|
||||
assert !pirate.created_on_changed?
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user