Module: ForestAdminAgent::AuditTrail::RecordState

Defined in:
lib/forest_admin_agent/audit_trail/record_state.rb

Overview

Rebuilds a record as it stood at a given instant by walking its history backwards from the record as it stands now, undoing every entry recorded after that instant (newest first).

Only audited columns are reconstructed — read-only, computed and DB-managed fields are never recorded, so they cannot be restored.

Class Method Summary collapse

Class Method Details

.at(current, entries) ⇒ Hash?

Returns the record at that instant, nil when it did not exist then.

Parameters:

  • current (Hash, nil)

    the record as it stands now, nil when it no longer exists

  • entries (Array<AuditRecord>)

    entries recorded after the instant, newest first

Returns:

  • (Hash, nil)

    the record at that instant, nil when it did not exist then



14
15
16
# File 'lib/forest_admin_agent/audit_trail/record_state.rb', line 14

def at(current, entries)
  entries.reduce(current) { |state, entry| undo(state, entry) }
end

.revert_columns(state, entry) ⇒ Object



36
37
38
39
40
# File 'lib/forest_admin_agent/audit_trail/record_state.rb', line 36

def revert_columns(state, entry)
  entry.previous_values.each_with_object((state || {}).dup) do |(column, previous), result|
    result[column] = Diff.revert(result[column], previous, entry.new_values[column])
  end
end

.undo(state, entry) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/forest_admin_agent/audit_trail/record_state.rb', line 18

def undo(state, entry)
  case entry.operation
  when 'create'
    # Created after the instant, so it did not exist then. An older entry can still bring a previous
    # life of the same id back — the walk carries on.
    nil
  when 'delete'
    # The delete recorded the whole record, which is exactly the state it was deleted from.
    entry.previous_values
  when 'update'
    revert_columns(state, entry)
  else
    # Action rows carry no field change: their two value columns hold what was submitted to the action
    # and what it answered, so applying either as a column change would corrupt the rebuild.
    state
  end
end