Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Provide more info on custom state attributes #62

Merged
merged 2 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading