aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_methods
diff options
context:
space:
mode:
authorRafael Mendonça França <rafaelmfranca@gmail.com>2014-06-07 14:52:30 -0300
committerRafael Mendonça França <rafaelmfranca@gmail.com>2014-06-07 14:52:30 -0300
commitc6e166b25e60a6594ab9aeba1738a835aa744d3e (patch)
tree923b1c614061b09aebcdf5b80d6546cd2d27e0f7 /activerecord/lib/active_record/attribute_methods
parentd95bcc9f1268821a48ea8c8181d9a7501338edc1 (diff)
parent368cca51d25fa15c0ddc8743b5904c4d5ce93e74 (diff)
downloadrails-c6e166b25e60a6594ab9aeba1738a835aa744d3e.tar.gz
rails-c6e166b25e60a6594ab9aeba1738a835aa744d3e.tar.bz2
rails-c6e166b25e60a6594ab9aeba1738a835aa744d3e.zip
Merge pull request #15562 from sgrif/sg-double-type-cast-dirty
Do not type cast twice on attribute assignment
Diffstat (limited to 'activerecord/lib/active_record/attribute_methods')
-rw-r--r--activerecord/lib/active_record/attribute_methods/dirty.rb31
1 files changed, 20 insertions, 11 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb
index 4e32b78e34..be438aba95 100644
--- a/activerecord/lib/active_record/attribute_methods/dirty.rb
+++ b/activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -55,7 +55,7 @@ module ActiveRecord
# optimistic locking) won't get written unless they get marked as changed
self.class.columns.each do |c|
attr, orig_value = c.name, c.default
- changed_attributes[attr] = orig_value if _field_changed?(attr, orig_value, @raw_attributes[attr])
+ changed_attributes[attr] = orig_value if _field_changed?(attr, orig_value)
end
end
@@ -63,19 +63,26 @@ module ActiveRecord
def write_attribute(attr, value)
attr = attr.to_s
- save_changed_attribute(attr, value)
+ old_value = old_attribute_value(attr)
- super(attr, value)
+ result = super(attr, value)
+ save_changed_attribute(attr, old_value)
+ result
end
- def save_changed_attribute(attr, value)
- # The attribute already has an unsaved change.
+ def save_changed_attribute(attr, old_value)
if attribute_changed?(attr)
- old = changed_attributes[attr]
- changed_attributes.delete(attr) unless _field_changed?(attr, old, value)
+ changed_attributes.delete(attr) unless _field_changed?(attr, old_value)
else
- old = clone_attribute_value(:read_attribute, attr)
- changed_attributes[attr] = old if _field_changed?(attr, old, value)
+ changed_attributes[attr] = old_value if _field_changed?(attr, old_value)
+ end
+ end
+
+ def old_attribute_value(attr)
+ if attribute_changed?(attr)
+ changed_attributes[attr]
+ else
+ clone_attribute_value(:read_attribute, attr)
end
end
@@ -93,8 +100,10 @@ module ActiveRecord
changed
end
- def _field_changed?(attr, old, value)
- column_for_attribute(attr).changed?(old, value)
+ def _field_changed?(attr, old_value)
+ new_value = read_attribute(attr)
+ raw_value = read_attribute_before_type_cast(attr)
+ column_for_attribute(attr).changed?(old_value, new_value, raw_value)
end
end
end