Skip to content

Commit

Permalink
docs: Provide more info on custom state attributes (#62)
Browse files Browse the repository at this point in the history
* docs: Provide more info on custom state attributes

* Update documentation/tutorials/getting-started-with-ash-state-machine.md

Co-authored-by: Zach Daniel <zachary.s.daniel@gmail.com>

---------

Co-authored-by: Zach Daniel <zachary.s.daniel@gmail.com>
  • Loading branch information
DriesCruyskens and zachdaniel authored Oct 22, 2024
1 parent 8c41dc5 commit 3276ece
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
2 changes: 1 addition & 1 deletion documentation/dsls/DSL:-AshStateMachine.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Provides tools for defining and working with resource-backed state machines.
| [`initial_states`](#state_machine-initial_states){: #state_machine-initial_states .spark-required} | `list(atom)` | | The allowed starting states of this state machine. |
| [`deprecated_states`](#state_machine-deprecated_states){: #state_machine-deprecated_states } | `list(atom)` | `[]` | A list of states that have been deprecated but are still valid. These will still be in the possible list of states, but `:*` will not include them. |
| [`extra_states`](#state_machine-extra_states){: #state_machine-extra_states } | `list(atom)` | `[]` | A list of states that may be used by transitions to/from `:*`. See the docs on wildcards for more. |
| [`state_attribute`](#state_machine-state_attribute){: #state_machine-state_attribute } | `atom` | `:state` | The attribute to store the state in. |
| [`state_attribute`](#state_machine-state_attribute){: #state_machine-state_attribute } | `atom` | `:state` | The attribute to store the state in. You don't have to declare an attribute yourself, but it is possible. See the tutorial for more information. |
| [`default_initial_state`](#state_machine-default_initial_state){: #state_machine-default_initial_state } | `atom` | | The default initial state |


Expand Down
41 changes: 41 additions & 0 deletions documentation/tutorials/getting-started-with-ash-state-machine.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,47 @@ actions do
end
```

## Declaring a custom state attribute

By default, a `:state` attribute is created on the resource that looks like this:

```elixir
attribute :state, :atom do
allow_nil? false
default AshStateMachine.Info.state_machine_initial_default_state(dsl_state)
public? true
constraints one_of: [
AshStateMachine.Info.state_machine_all_states(dsl_state)
]
end
```

You can change the name of this attribute, without declaring an attribute yourself, like so:

```elixir
state_machine do
initial_states([:pending])
default_initial_state(:pending)
state_attribute(:alternative_state) # <-- save state in an attribute named :alternative_state
end
```

If you need more control, you can declare the attribute yourself on the resource:

```elixir
attributes do
attribute :alternative_state, :atom do
allow_nil? false
default :issued
public? true
constraints one_of: [:issued, :sold, :reserved, :retired]
end
end
```

Be aware that the type of this attribute needs to be `:atom` or a type created with `Ash.Type.Enum`. Both the `default` and list of values need to be correct!


## 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`.
Expand Down

0 comments on commit 3276ece

Please sign in to comment.