Module: Acta::ProjectionManaged

Extended by:
ActiveSupport::Concern
Defined in:
lib/acta/projection_managed.rb

Overview

Marks an ActiveRecord model as projection-managed: its rows are maintained by an Acta::Projection from the event log, so writes from anywhere else (controllers, console, rake tasks, callbacks on other models) bypass the log and break Acta.rebuild!‘s determinism.

Opt in with ‘acta_managed!` on the AR class:

class Trail < ApplicationRecord
  acta_managed!   # raise on out-of-band writes
end

class TrailAlias < ApplicationRecord
  acta_managed! on_violation: :warn   # warn instead, for incremental migration
end

Inside an ‘Acta::Projection` `on EventClass do |e| … end` block (or during `Acta.rebuild!`’s truncate phase), ‘Acta::Projection.applying?` is true and writes are allowed. Outside, they raise `Acta::ProjectionWriteError` (or warn if so configured).

Tests, migrations, and one-off backfills can wrap intentional out-of-band writes in ‘Acta::Projection.applying! { … }` to bypass the safety net explicitly.

Defined Under Namespace

Modules: ClassWriteGuards

Constant Summary collapse

GUARDED_CLASS_METHODS =
%i[
  update_all
  delete_all
  insert
  insert!
  insert_all
  insert_all!
  upsert
  upsert_all
].freeze
GUARDED_INSTANCE_METHODS =
%i[
  update_columns
  update_column
].freeze
VALID_VIOLATION_ACTIONS =
%i[ raise warn ].freeze

Class Method Summary collapse

Class Method Details

.assert_projection_applying!(model_class, write_method) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
# File 'lib/acta/projection_managed.rb', line 90

def self.assert_projection_applying!(model_class, write_method)
  return if Acta::Projection.applying?

  action = model_class.acta_on_violation
  case action
  when :raise
    raise Acta::ProjectionWriteError.new(model_class:, write_method:)
  when :warn
    warn "[acta] #{Acta::ProjectionWriteError.new(model_class:, write_method:).message}"
  end
end