Skip to content

Commit

Permalink
Fix handling of dirty time zone aware attributes
Browse files Browse the repository at this point in the history
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
  • Loading branch information
nowaterlili authored and pixeltrix committed Jan 26, 2013
1 parent 0b5d3f3 commit bc982cb
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 2 deletions.
28 changes: 28 additions & 0 deletions activerecord/CHANGELOG.md
@@ -1,5 +1,33 @@
## Rails 4.0.0 (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

*Lilibeth De La Cruz*

* When `#count` is used in conjunction with `#uniq` we perform `count(:distinct => true)`.
Fix #6865.

Expand Down
Expand Up @@ -40,9 +40,9 @@ def #{attr_name}=(original_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
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
Expand Down
2 changes: 2 additions & 0 deletions activerecord/test/cases/dirty_test.rb
Expand Up @@ -79,6 +79,8 @@ def test_time_attributes_changes_with_time_zone
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

Expand Down

0 comments on commit bc982cb

Please sign in to comment.