Module: OpenLoam::Workflow
- Extended by:
- ActiveSupport::Concern
- Included in:
- PendingAction
- Defined in:
- lib/open_loam/workflow.rb
Overview
Declarative state machine for a tenant-scoped entity: the states a record can be in, the legal moves between them, and who may make each move.
class PurchaseOrder < OpenLoam::TenantRecord
include OpenLoam::Workflow
workflow :status, initial: "draft" do
state "draft"
state "pending_approval"
state "approved"
transition :submit, from: "draft", to: "pending_approval"
transition :approve, from: "pending_approval", to: "approved", roles: [:manager]
end
end
order.submit! # draft -> pending_approval, publishes
# "<domain>.purchase_order.submit"
order.workflow_transitions_available # => [:approve] for a manager, [] for anyone else
PurchaseOrder.open_loam_workflow # the frozen definition, for agents and admin UI
What this buys over hand-rolled if status == "draft": an illegal move
raises instead of silently writing a bad value, the roles that may move a
record are declared in one readable place instead of scattered across
controllers, and the whole machine is introspectable.
The state change itself is an ordinary attribute write, so OpenLoam::Auditable records it like any other change — a workflow adds no second audit trail.
Defined Under Namespace
Classes: Builder, Definition, Transition
Instance Method Summary collapse
- #open_loam_workflow_state ⇒ Object
-
#workflow_transitions_available ⇒ Object
Transition names that are legal right now: from this record's state, for the actor in OpenLoam::Current.
Instance Method Details
#open_loam_workflow_state ⇒ Object
182 183 184 |
# File 'lib/open_loam/workflow.rb', line 182 def open_loam_workflow_state self[self.class.open_loam_workflow.column].to_s end |
#workflow_transitions_available ⇒ Object
Transition names that are legal right now: from this record's state, for the actor in OpenLoam::Current. Never raises — an admin screen asks this to decide which buttons to render.
174 175 176 177 178 179 180 |
# File 'lib/open_loam/workflow.rb', line 174 def workflow_transitions_available role = open_loam_workflow_role self.class.open_loam_workflow.transitions_from(open_loam_workflow_state) .select { |transition| transition.roles.empty? || transition.roles.include?(role) } .map(&:name) end |