Class: Plutonium::Wizard::Base
- Inherits:
-
Object
- Object
- Plutonium::Wizard::Base
- Includes:
- ActiveModel::Model, Definition::Presentable, DSL
- Defined in:
- lib/plutonium/wizard/base.rb
Overview
Author-facing base class for wizards (§2). A wizard declares ordered steps
(with their own field surface, branching condition:, and optional per-step
on_submit/on_rollback), an optional terminal review step, and commits
at the end via execute.
This class is pure object behaviour — declaring the DSL, exposing the
ordered steps, the union data snapshot, and the anchor/fail!
accessors. HTTP/runner/store wiring lives elsewhere.
Instance Attribute Summary collapse
-
#anchor ⇒ Object
The record this wizard was launched against (§3).
-
#current_scoped_entity ⇒ Object
Identity/concurrency context (§4.5), supplied by the runner/driving layer so
concurrency_keyresolvers and the tenancy fold can reach them. -
#current_user ⇒ Object
Identity/concurrency context (§4.5), supplied by the runner/driving layer so
concurrency_keyresolvers and the tenancy fold can reach them. -
#data_attributes ⇒ Object
Returns the value of attribute data_attributes.
-
#scope ⇒ Object
writeonly
Sets the attribute scope.
-
#token ⇒ Object
writeonly
Sets the attribute token.
-
#view_context ⇒ Object
Returns the value of attribute view_context.
-
#wizard_token ⇒ Object
Identity/concurrency context (§4.5), supplied by the runner/driving layer so
concurrency_keyresolvers and the tenancy fold can reach them.
Class Method Summary collapse
-
.data_step_classes ⇒ Object
The per-step typed sub-object classes (=> Class), built once per wizard class from Base.data_steps_spec and reused for every
datasnapshot (the container is cheap to instantiate; the classes aren't). -
.data_steps_spec ⇒ Object
Per-step data spec (=> {schema:, options:, structured:}), used to build the step-keyed
datacontainer (§2.6). -
.inline_validation_classes ⇒ Object
Per-step typed classes carrying ONLY the step's INLINE
validates(no imported form validators — those are validated separately via the transient model, so folding them in here would double-report).
Instance Method Summary collapse
-
#authorize? ⇒ Boolean
Entry authorization (§5.2/§6.5).
-
#concurrency_key_value ⇒ Object
Resolve this wizard's concurrency_key VALUE(S) in the wizard context (§4.2), with the tenant ALWAYS folded in (§4.4).
-
#data ⇒ Object
The step-keyed
datasnapshot (§2.6), reconstituted from the nested stageddata_attributes(=> {field => value}). -
#execute ⇒ Object
The at-end commit hook (§2.3).
-
#initialize(view_context: nil) ⇒ Base
constructor
A new instance of Base.
-
#persisted ⇒ Object
Records the per-step
on_submit/persistmacro registers (§2.2), as a LAZY view over the stored GIDs: a key is located on first read and memoized, so a request that never readspersistedissues zero locates (§4.5). -
#persisted_gid_source=(source) ⇒ Object
The
{ "step_key" => [gids] }source the runner injects from the stored state, backing the lazypersistedview.
Methods included from Definition::Presentable
Constructor Details
#initialize(view_context: nil) ⇒ Base
Returns a new instance of Base.
58 59 60 61 62 |
# File 'lib/plutonium/wizard/base.rb', line 58 def initialize(view_context: nil, **) @view_context = view_context @data_attributes = {} super() end |
Instance Attribute Details
#anchor ⇒ Object
The record this wizard was launched against (§3). Raises when the wizard
was not declared anchored — never returns nil.
141 142 143 144 145 146 |
# File 'lib/plutonium/wizard/base.rb', line 141 def anchor unless self.class.anchored? raise NotAnchoredError, "#{self.class} is not declared `anchored`" end @anchor end |
#current_scoped_entity ⇒ Object
Identity/concurrency context (§4.5), supplied by the runner/driving layer
so concurrency_key resolvers and the tenancy fold can reach them.
wizard_token is the per-run id (the identity for guest/repeatable runs,
available inside concurrency_key) — NOT a pre-auth principal that
survives login.
43 44 45 |
# File 'lib/plutonium/wizard/base.rb', line 43 def current_scoped_entity @current_scoped_entity end |
#current_user ⇒ Object
Identity/concurrency context (§4.5), supplied by the runner/driving layer
so concurrency_key resolvers and the tenancy fold can reach them.
wizard_token is the per-run id (the identity for guest/repeatable runs,
available inside concurrency_key) — NOT a pre-auth principal that
survives login.
43 44 45 |
# File 'lib/plutonium/wizard/base.rb', line 43 def current_user @current_user end |
#data_attributes ⇒ Object
Returns the value of attribute data_attributes.
34 35 36 |
# File 'lib/plutonium/wizard/base.rb', line 34 def data_attributes @data_attributes end |
#scope=(value) ⇒ Object (writeonly)
Sets the attribute scope
36 37 38 |
# File 'lib/plutonium/wizard/base.rb', line 36 def scope=(value) @scope = value end |
#token=(value) ⇒ Object (writeonly)
Sets the attribute token
36 37 38 |
# File 'lib/plutonium/wizard/base.rb', line 36 def token=(value) @token = value end |
#view_context ⇒ Object
Returns the value of attribute view_context.
35 36 37 |
# File 'lib/plutonium/wizard/base.rb', line 35 def view_context @view_context end |
#wizard_token ⇒ Object
Identity/concurrency context (§4.5), supplied by the runner/driving layer
so concurrency_key resolvers and the tenancy fold can reach them.
wizard_token is the per-run id (the identity for guest/repeatable runs,
available inside concurrency_key) — NOT a pre-auth principal that
survives login.
43 44 45 |
# File 'lib/plutonium/wizard/base.rb', line 43 def wizard_token @wizard_token end |
Class Method Details
.data_step_classes ⇒ Object
The per-step typed sub-object classes (=> Class), built once
per wizard class from data_steps_spec and reused for every data
snapshot (the container is cheap to instantiate; the classes aren't).
84 85 86 87 88 |
# File 'lib/plutonium/wizard/base.rb', line 84 def data_step_classes @data_step_classes ||= data_steps_spec.transform_values do |spec| Data.class_for(spec[:schema], options: spec[:options], structured: spec[:structured], validations: spec[:validations]) end end |
.data_steps_spec ⇒ Object
Per-step data spec (=> {schema:, options:, structured:}), used
to build the step-keyed data container (§2.6). Each step contributes its
OWN schema/options/structured — no cross-step union, so two steps may share
a field name without colliding. using: imports are already composed into
each step's attribute_schema.
70 71 72 73 74 75 76 77 78 79 |
# File 'lib/plutonium/wizard/base.rb', line 70 def data_steps_spec steps.reject(&:review?).each_with_object({}) do |step, acc| acc[step.key.to_sym] = { schema: step.attribute_schema, options: step., structured: step_structured_schema(step), validations: step.validations + step.imported_form_validators } end end |
.inline_validation_classes ⇒ Object
Per-step typed classes carrying ONLY the step's INLINE validates (no
imported form validators — those are validated separately via the
transient model, so folding them in here would double-report). Built once
per wizard class and reused by the runner's inline validation, which
otherwise recompiles an equivalent anonymous class on every validate
call (and validate runs many times per render). {step_key => Class},
omitting steps with no inline validations.
97 98 99 100 101 102 |
# File 'lib/plutonium/wizard/base.rb', line 97 def inline_validation_classes @inline_validation_classes ||= steps.reject(&:review?).each_with_object({}) do |step, acc| next if step.validations.blank? acc[step.key.to_sym] = Data.class_for(step.attribute_schema, validations: step.validations) end end |
Instance Method Details
#authorize? ⇒ Boolean
Entry authorization (§5.2/§6.5). Authors override it; false → 403. Default allow — resource-mounted surfaces additionally gate via the action policy.
182 |
# File 'lib/plutonium/wizard/base.rb', line 182 def = true |
#concurrency_key_value ⇒ Object
Resolve this wizard's concurrency_key VALUE(S) in the wizard context
(§4.2), with the tenant ALWAYS folded in (§4.4). Returns nil when no
concurrency_key is declared (→ tokened identity). The returned value is
an array [*key_values, tenant_gid]; InstanceKey.concurrency serializes
it. The tenant is appended even when nil so the digest is stable.
153 154 155 156 157 158 159 |
# File 'lib/plutonium/wizard/base.rb', line 153 def concurrency_key_value resolver = self.class.concurrency_key_resolver return nil unless resolver key = instance_exec(&resolver) [*Array.wrap(key), current_scoped_entity] end |
#data ⇒ Object
The step-keyed data snapshot (§2.6), reconstituted from the nested staged
data_attributes (=> {field => value}). Addressed as
data.<step>.<field>; data[:step] for dynamic access.
135 136 137 |
# File 'lib/plutonium/wizard/base.rb', line 135 def data @data ||= Data::Container.new(self.class.data_step_classes, data_attributes) end |
#execute ⇒ Object
The at-end commit hook (§2.3). Authors override it.
176 177 178 |
# File 'lib/plutonium/wizard/base.rb', line 176 def execute raise NotImplementedError, "#{self.class} must implement #execute" end |
#persisted ⇒ Object
Records the per-step on_submit/persist macro registers (§2.2), as a
LAZY view over the stored GIDs: a key is located on first read and
memoized, so a request that never reads persisted issues zero locates
(§4.5). Records set this request (the persist macro) are live already.
171 172 173 |
# File 'lib/plutonium/wizard/base.rb', line 171 def persisted @persisted ||= LazyPersisted.new end |
#persisted_gid_source=(source) ⇒ Object
The { "step_key" => [gids] } source the runner injects from the stored
state, backing the lazy persisted view. Reassigning it resets the memo.
163 164 165 |
# File 'lib/plutonium/wizard/base.rb', line 163 def persisted_gid_source=(source) @persisted = LazyPersisted.new(source) end |