Class: TypedEAV::ValueVersion
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- TypedEAV::ValueVersion
- Defined in:
- app/models/typed_eav/value_version.rb
Overview
Append-only audit log row for a TypedEAV::Value mutation. One row per :create / :update / :destroy event when the host entity opted into versioning AND the gem-level master switch is on. Written by TypedEAV::Versioning::Subscriber (plan 04-02), read via Value#history (plan 04-03) or directly via this model.
Schema invariants (locked at 04-CONTEXT.md)
before_valueandafter_valueare jsonb hashes keyed by typed- column name (e.g., 42). Empty {} means "no recorded value" (typical of a :create event's before, or a :destroy event's after). null means "recorded nil" (a deliberate clear). The two are NOT semantically equivalent.change_typeis one of "create" | "update" | "destroy" — string, not enum, for forward compat. Phase 04 ships these three; future phases may extend the validator.value_idandfield_idare nullable: ON DELETE SET NULL on both FKs preserves the audit log when the live Value/Field is destroyed (matches Phase 02's cascade pattern for typed_eav_values.field_id).(entity_type, entity_id)is the durable identity. Even after the Value row is destroyed and value_id is NULLed, the entity tuple tells consumers which host record this version belonged to.changed_byis a plain string — Lead's plan-time decision (see 04-01-PLAN §Plan-time decisions §1). Apps resolve to AR records on the read side:User.find_by(id: version.changed_by).
Why no default_scope
Append-only logs benefit from explicit ordering at the call site
(Value#history.order(changed_at: :desc)) rather than a hidden
default_scope that consumers must learn to override. Mirrors the
gem's existing convention (no default_scope on Value, Field::Base,
Section, Option). The idx_te_vvs_value covering index serves the
(value_id, changed_at DESC) query path natively.
Constant Summary collapse
- CHANGE_TYPES =
change_type closed set. Mirrors the Phase 02 field_dependent validator pattern (field/base.rb:56-59) — string column + inclusion validator narrows the set at the model layer while keeping schema migrations additive.
%w[create update destroy].freeze