module ActiveRecord::AttributeMethods::Dirty

def _create_record(attribute_names = attribute_names_for_partial_inserts)

def _create_record(attribute_names = attribute_names_for_partial_inserts)
  id = super
  changes_applied
  id
end

def _touch_row(attribute_names, time)

def _touch_row(attribute_names, time)
  @_touch_attr_names = Set.new(attribute_names)
  affected_rows = super
  if @_skip_dirty_tracking ||= false
    clear_attribute_changes(@_touch_attr_names)
    return affected_rows
  end
  changes = {}
  @attributes.keys.each do |attr_name|
    next if @_touch_attr_names.include?(attr_name)
    if attribute_changed?(attr_name)
      changes[attr_name] = _read_attribute(attr_name)
      _write_attribute(attr_name, attribute_was(attr_name))
      clear_attribute_change(attr_name)
    end
  end
  changes_applied
  changes.each { |attr_name, value| _write_attribute(attr_name, value) }
  affected_rows
ensure
  @_touch_attr_names, @_skip_dirty_tracking = nil, nil
end

def _update_record(attribute_names = attribute_names_for_partial_updates)

def _update_record(attribute_names = attribute_names_for_partial_updates)
  affected_rows = super
  changes_applied
  affected_rows
end

def attribute_before_last_save(attr_name)

attribute_before_last_save("name").
invoked as +name_before_last_save+ instead of
attribute before the save that triggered the callbacks to run. It can be
This method is useful in after callbacks to get the original value of an

Returns the original value of an attribute before the last save.
def attribute_before_last_save(attr_name)
  mutations_before_last_save.original_value(attr_name.to_s)
end

def attribute_change_to_be_saved(attr_name)

original value and the new value about to be saved.
If the attribute will change, the result will be an array containing the

attribute_change_to_be_saved("name").
be invoked as +name_change_to_be_saved+ instead of
change to an attribute that will occur when the record is saved. It can
This method is useful in validations and before callbacks, to see the

next save.
Returns the change to an attribute that will be persisted during the
def attribute_change_to_be_saved(attr_name)
  mutations_from_database.change_to_attribute(attr_name.to_s)
end

def attribute_in_database(attr_name)

attribute_in_database("name").
saved. It can be invoked as +name_in_database+ instead of
original value of an attribute prior to any changes about to be
This method is useful in validations and before callbacks, to see the

saved.
in-memory value that will be persisted the next time the record is
Returns the value of an attribute in the database, as opposed to the
def attribute_in_database(attr_name)
  mutations_from_database.original_value(attr_name.to_s)
end

def attribute_names_for_partial_inserts

def attribute_names_for_partial_inserts
  if partial_inserts?
    changed_attribute_names_to_save
  else
    attribute_names.reject do |attr_name|
      if column_for_attribute(attr_name).default_function
        !attribute_changed?(attr_name)
      end
    end
  end
end

def attribute_names_for_partial_updates

def attribute_names_for_partial_updates
  partial_updates? ? changed_attribute_names_to_save : attribute_names
end

def attributes_in_database

values about to be saved).
original attribute values in the database (as opposed to the in-memory
The hash keys are the attribute names, and the hash values are the

next saved.
Returns a hash of the attributes that will change when the record is
def attributes_in_database
  mutations_from_database.changed_values
end

def changed_attribute_names_to_save

the record is next saved.
Returns an array of the names of any attributes that will change when
def changed_attribute_names_to_save
  mutations_from_database.changed_attribute_names
end

def changes_to_save

the next save.
Returns a hash containing all the changes that will be persisted during
def changes_to_save
  mutations_from_database.changes
end

def has_changes_to_save?

Will the next call to +save+ have any changes to persist?
def has_changes_to_save?
  mutations_from_database.any_changes?
end

def reload(*)

reload the record and clears changed attributes.
def reload(*)
  super.tap do
    @mutations_before_last_save = nil
    @mutations_from_database = nil
  end
end

def saved_change_to_attribute(attr_name)

saved_change_to_attribute("name").
invoked as +saved_change_to_name+ instead of
attribute during the save that triggered the callbacks to run. It can be
This method is useful in after callbacks, to see the change in an

original value and the saved value.
attribute was changed, the result will be an array containing the
Returns the change to an attribute during the last save. If the
def saved_change_to_attribute(attr_name)
  mutations_before_last_save.change_to_attribute(attr_name.to_s)
end

def saved_change_to_attribute?(attr_name, **options)

changed to the given value
+to+ When passed, this method will return false unless the value was

value is equal to the given option
+from+ When passed, this method will return false unless the original

==== Options

saved_change_to_attribute?("name").
be invoked as +saved_change_to_name?+ instead of
was changed during the save that triggered the callbacks to run. It can
This method is useful in after callbacks to determine if an attribute

Did this attribute change when we last saved?
def saved_change_to_attribute?(attr_name, **options)
  mutations_before_last_save.changed?(attr_name.to_s, **options)
end

def saved_changes

Returns a hash containing all the changes that were just saved.
def saved_changes
  mutations_before_last_save.changes
end

def saved_changes?

Did the last call to +save+ have any changes to change?
def saved_changes?
  mutations_before_last_save.any_changes?
end

def will_save_change_to_attribute?(attr_name, **options)

changed to the given value
+to+ When passed, this method will return false unless the value will be

value is equal to the given option
+from+ When passed, this method will return false unless the original

==== Options

will_save_change_to_attribute?("name").
invoked as +will_save_change_to_name?+ instead of
if the next call to +save+ will change a particular attribute. It can be
This method is useful in validations and before callbacks to determine

Will this attribute change the next time we save?
def will_save_change_to_attribute?(attr_name, **options)
  mutations_from_database.changed?(attr_name.to_s, **options)
end