module ActiveModel::Datastore::TrackChanges
Public Instance Methods
# File lib/active_model/datastore/track_changes.rb, line 21 def exclude_from_save? @exclude_from_save.nil? ? false : @exclude_from_save end
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
# 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
# File lib/active_model/datastore/track_changes.rb, line 9 def tracked_attributes [] end
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