# File lib/active_record/attribute_methods/dirty.rb, line 80 80: def _field_changed?(attr, old, value) 81: if column = column_for_attribute(attr) 82: if column.number? && (changes_from_nil_to_empty_string?(column, old, value) || 83: changes_from_zero_to_string?(old, value)) 84: value = nil 85: else 86: value = column.type_cast(value) 87: end 88: end 89: 90: old != value 91: end
# File lib/active_record/attribute_methods/dirty.rb, line 97 97: def changes_from_nil_to_empty_string?(column, old, value) 98: # For nullable numeric columns, NULL gets stored in database for blank (i.e. '') values. 99: # Hence we don't record it as a change if the value changes from nil to ''. 100: # If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll 101: # be typecast back to 0 (''.to_i => 0) 102: column.null && (old.nil? || old == 0) && value.blank? 103: end
# File lib/active_record/attribute_methods/dirty.rb, line 105 105: def changes_from_zero_to_string?(old, value) 106: # For columns with old 0 and value non-empty string 107: old == 0 && value.is_a?(String) && value.present? && value != '0' 108: end
# File lib/active_record/attribute_methods/dirty.rb, line 93 93: def clone_with_time_zone_conversion_attribute?(attr, old) 94: old.class.name == "Time" && time_zone_aware_attributes && !self.skip_time_zone_conversion_for_attributes.include?(attr.to_sym) 95: end
# File lib/active_record/attribute_methods/dirty.rb, line 70 70: def update(*) 71: if partial_updates? 72: # Serialized attributes should always be written in case they've been 73: # changed in place. 74: super(changed | (attributes.keys & self.class.serialized_attributes.keys)) 75: else 76: super 77: end 78: end
Wrap write_attribute to remember original attribute value.
# File lib/active_record/attribute_methods/dirty.rb, line 52 52: def write_attribute(attr, value) 53: attr = attr.to_s 54: 55: # The attribute already has an unsaved change. 56: if attribute_changed?(attr) 57: old = @changed_attributes[attr] 58: @changed_attributes.delete(attr) unless _field_changed?(attr, old, value) 59: else 60: old = clone_attribute_value(:read_attribute, attr) 61: # Save Time objects as TimeWithZone if time_zone_aware_attributes == true 62: old = old.in_time_zone if clone_with_time_zone_conversion_attribute?(attr, old) 63: @changed_attributes[attr] = old if _field_changed?(attr, old, value) 64: end 65: 66: # Carry on. 67: super(attr, value) 68: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.