module ActiveModel::Datastore::TrackChanges

Public Instance Methods

exclude_from_save?() click to toggle source
# File lib/active_model/datastore/track_changes.rb, line 21
def exclude_from_save?
  @exclude_from_save.nil? ? false : @exclude_from_save
end
reload!() click to toggle source

Resets the ActiveModel::Dirty tracked changes.

# File lib/active_model/datastore/track_changes.rb, line 16
def reload!
  clear_changes_information
  self.exclude_from_save = false
end
remove_unmodified_children() click to toggle source
# File lib/active_model/datastore/track_changes.rb, line 84
def remove_unmodified_children
  return unless tracked_attributes.present? && nested_attributes?

  nested_attributes.each do |attr|
    with_changes = Array(send(attr.to_sym)).select(&:values_changed?)
    send("#{attr}=", with_changes)
  end
  nested_attributes.delete_if { |attr| Array(send(attr.to_sym)).size.zero? }
end
tracked_attributes() click to toggle source
# File lib/active_model/datastore/track_changes.rb, line 9
def tracked_attributes
  []
end
values_changed?() click to toggle source

Determines if any attribute values have changed using ActiveModel::Dirty. For attributes enabled for change tracking compares changed values. All values submitted from an HTML form are strings, thus a string of 25.0 doesn't match an original float of 25.0. Call this method after valid? to allow for any type coercing occurring before saving to datastore.

Consider the scenario in which the user submits an unchanged form value named `area`. The initial value from datastore is a float of 25.0, which during assign_attributes is set to a string of '25.0'. It is then coerced back to a float of 25.0 during a validation callback. The area_changed? will return true, yet the value is back where is started.

For example:

class Shapes
  include ActiveModel::Datastore

  attr_accessor :area
  enable_change_tracking :area
  after_validation :format_values

  def format_values
    format_property_value :area, :float
  end

  def update(params)
    assign_attributes(params)
    if valid?
      puts values_changed?
      puts area_changed?
      p area_change
    end
  end
end

Will result in this:

values_changed? false
area_changed? true # This is correct, as area was changed but the value is identical.
area_change [0, 0]

If none of the tracked attributes have changed, the `exclude_from_save` attribute is set to true and the method returns false.

# File lib/active_model/datastore/track_changes.rb, line 69
def values_changed?
  unless tracked_attributes.present?
    raise TrackChangesError, 'Object has not been configured for change tracking.'
  end

  changed = marked_for_destruction? ? true : false
  tracked_attributes.each do |attr|
    break if changed

    changed = send(attr) != send("#{attr}_was") if send("#{attr}_changed?")
  end
  self.exclude_from_save = !changed
  changed
end