View Source Getting Started with State Machines
Get familiar with Ash resources
If you haven't already, read the Ash Getting Started Guide, and familiarize yourself with Ash and Ash resources.
Bring in the ash_state_machine dependency
{:ash_state_machine, "~> 0.2.6"}
Add the extension to your resource
use Ash.Resource,
extensions: [AshStateMachine]
Add initial states, and a default initial state
use Ash.Resource,
extensions: [AshStateMachine]
...
state_machine do
initial_states [:pending]
default_initial_state :pending
end
Add allowed transitions
state_machine do
initial_states [:pending]
default_initial_state :pending
transitions do
# `:begin` action can move state from `:pending` to `:started`/`:aborted`
transition :begin, from: :pending, to: [:started, :aborted]
end
end
Use transition_state
in your actions
For simple/static state transitions
actions do
update :begin do
# for a static state transition
change transition_state(:started)
end
end
For dynamic/conditional state transitions
defmodule Start do
use Ash.Resource.Change
def change(changeset, _, _) do
if ready_to_start?(changeset) do
AshStateMachine.transition_state(changeset, :started)
else
AshStateMachine.transition_state(changeset, :aborted)
end
end
end
actions do
update :begin do
# for a dynamic state transition
change Start
end
end
Making a resource into a state machine
The concept of a state machine (in this case a "Finite State Machine"), essentially involves a single state
, with specified transitions between states. For example, you might have an order state machine with states [:pending, :on_its_way, :delivered]
. However, you can't go from :pending
to :delivered
(probably), and so you want to only allow certain transitions in certain circumstances, i.e :pending -> :on_its_way -> :delivered
.
This extension's goal is to help you write clear and clean state machines, with all of the extensibility and power of Ash resources and actions.