Module: ActiveModel::Datastore::TrackChanges

Extended by:
ActiveSupport::Concern
Included in:
ActiveModel::Datastore
Defined in:
lib/active_model/datastore/track_changes.rb

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#exclude_from_save?Boolean

Returns:

  • (Boolean)


21
22
23
# File 'lib/active_model/datastore/track_changes.rb', line 21

def exclude_from_save?
  @exclude_from_save.nil? ? false : @exclude_from_save
end

#reload!Object

Resets the ActiveModel::Dirty tracked changes.



16
17
18
19
# File 'lib/active_model/datastore/track_changes.rb', line 16

def reload!
  clear_changes_information
  self.exclude_from_save = false
end

#remove_unmodified_childrenObject



84
85
86
87
88
89
90
91
92
# 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)).empty? }
end

#tracked_attributesObject



9
10
11
# File 'lib/active_model/datastore/track_changes.rb', line 9

def tracked_attributes
  []
end

#values_changed?Boolean

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.

Returns:

  • (Boolean)


69
70
71
72
73
74
75
76
77
78
79
80
81
82
# 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