Module: TrackChanges::Model::InstanceMethods

Defined in:
lib/track_changes/model.rb

Instance Method Summary collapse

Instance Method Details

#persist_tracked_changesObject

Compares the last tracked changes to the current state and saves a diff of the changes



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/track_changes/model.rb', line 65

def persist_tracked_changes
  return if track_changes == false

  new_record = was_new_record_before_save?
  action     = new_record ? 'create' : 'update'
  changes_by = track_changes_by.is_a?(ActiveRecord::Base) ? track_changes_by.id : track_changes_by

  if snapshot
    snapshot.create_diff(:action => action, :changes_by => changes_by)
    snapshot.update
  elsif new_record
    create_snapshot
    snapshot.create_diff(:action => action, :changes_by => changes_by, :from => {}, :to => snapshot.state)
  else # We started tracking changes after the item was created
    create_snapshot
    snapshot.create_diff(:action => action, :changes_by => changes_by, :from => {})
  end
end

#track_changes_byObject



60
61
62
# File 'lib/track_changes/model.rb', line 60

def track_changes_by
  @track_changes_by || TrackChanges.default_attribution
end

#tracked_change(**changes) ⇒ Object

Filters tracked change diffs to only those where the given attributes changed to the specified values.

It builds a scope that matches records where each given attribute in ‘to` has the specified value.

Example:

model.tracked_change(status: "approved", priority: "high")
# => returns diffs where status became "approved" and priority became "high"

Params:

  • changes (keyword arguments): One or more attribute-value pairs to match against the ‘to` column.

Returns:

  • ActiveRecord::Relation: A filtered scope on the diffs table.



107
108
109
110
111
112
113
# File 'lib/track_changes/model.rb', line 107

def tracked_change(**changes)
  table_name = diffs.quoted_table_name
  column_name = diffs.connection.quote_column_name(:to)
  changes.reduce(diffs) do |scope, (attribute, value)|
    scope.where("#{table_name}.#{column_name} ->> ? = ?", attribute, value)
  end
end

#was_new_record_before_save?Boolean

Returns:



84
85
86
87
88
89
90
91
92
# File 'lib/track_changes/model.rb', line 84

def was_new_record_before_save?
  if !respond_to?(:attribute_before_last_save) # Rails < 6
    id_was.blank?
  elsif saved_change_to_attribute?(:id) # Rails <=5
    attribute_before_last_save(:id).blank?
  else # Allow this method to be used outside of a transaction, e.g. after a bulk update
    new_record?
  end
end