### Example State Transition with Machinery in Elixir Source: https://github.com/joaomdmoura/machinery/blob/master/README.md Provides a concrete example of using `Machinery.transition_to/3` to change the state of a user struct to 'completed', demonstrating the function call and the expected `{:ok, updated_struct}` return value. ```Elixir user = Accounts.get_user!(1) {:ok, updated_user} = Machinery.transition_to(user, UserStateMachine, "completed") ``` -------------------------------- ### Example Before and After Transition Callbacks in Machinery (Elixir) Source: https://github.com/joaomdmoura/machinery/blob/master/README.md Provides a practical example of implementing the `before_transition/2` and `after_transition/2` callbacks. It demonstrates how to define specific callback functions for transitions *to* the "partial" state (before) and *to* the "completed" state (after) to perform desired side effects. Both functions return the struct. ```Elixir defmodule YourProject.UserStateMachine do use Machinery, states: ["created", "partial", "completed"], transitions: %{ "created" => ["partial", "completed"], "partial" => "completed" } def before_transition(struct, "partial") do # ... overall desired side effects struct end def after_transition(struct, "completed") do # ... overall desired side effects struct end end ``` -------------------------------- ### Example Guard Transition Callback in Machinery (Elixir) Source: https://github.com/joaomdmoura/machinery/blob/master/README.md Provides a practical example of implementing the `guard_transition/2` callback. It demonstrates how to check a condition (`Map.get(struct, :missing_fields) == true`) and return `{:error, "cause"}` to prevent the transition to the "completed" state if the condition is met. ```Elixir defmodule YourProject.UserStateMachine do use Machinery, states: ["created", "completed"], transitions: %{"created" => "completed"} # Guard the transition to the "completed" state. def guard_transition(struct, "completed") do if Map.get(struct, :missing_fields) == true do {:error, "There are missing fields"} end end end ``` -------------------------------- ### Implementing Log Transition Callback in Machinery (Elixir) Source: https://github.com/joaomdmoura/machinery/blob/master/README.md Demonstrates how to implement the `log_transition/2` callback in a Machinery state machine module. This function is executed after a state transition is persisted and is used for logging or other side effects. It receives the struct and the next state string and must return the struct. An optional third argument for metadata is also mentioned. ```Elixir defmodule YourProject.UserStateMachine do alias YourProject.Accounts use Machinery, states: ["created", "completed"], transitions: %{"created" => "completed"} # You can add an optional third argument for the extra metadata. def log_transition(struct, _next_state) do # Log transition here. # ... # `log_transition` should always return the struct struct end end ``` -------------------------------- ### Declaring State Machine Module in Elixir Source: https://github.com/joaomdmoura/machinery/blob/master/README.md Shows how to define a state machine module by importing `Machinery` and configuring it with the state field name, a list of states, and a map of allowed transitions, including wildcard transitions. ```Elixir defmodule YourProject.UserStateMachine do use Machinery, field: :custom_state_name, # Optional, default value is `:field` states: ["created", "partial", "completed", "canceled"], transitions: %{ "created" => ["partial", "completed"], "partial" => "completed", "*" => "canceled" } end ``` -------------------------------- ### Defining Before and After Transition Callback Signatures in Machinery (Elixir) Source: https://github.com/joaomdmoura/machinery/blob/master/README.md Shows the function signatures for the `before_transition/2` and `after_transition/2` callbacks in a Machinery state machine. These callbacks are used to perform side effects before or after a transition occurs. They receive the struct and the target state string (which can be pattern matched) and must return the struct. Optional third arguments for metadata are available. ```Elixir # Before and After callbacks should return the struct. # You can add an optional third argument for the extra metadata. def before_transition(struct, "state"), do: struct def after_transition(struct, "state"), do: struct ``` -------------------------------- ### Defining Guard Transition Callback Signature in Machinery (Elixir) Source: https://github.com/joaomdmoura/machinery/blob/master/README.md Shows the function signature for the `guard_transition/2` callback in a Machinery state machine. This function is used to define conditions that must be met before a transition is allowed. It receives the struct and the target state string, which can be used for pattern matching. An optional third argument for metadata is available. ```Elixir # The second argument is used to pattern match into the state # and guard the transition to it. # # You can add an optional third argument for the extra metadata. def guard_transition(struct, "guarded_state") do # Your guard logic here end ``` -------------------------------- ### Implementing State Persistence Callback in Elixir Source: https://github.com/joaomdmoura/machinery/blob/master/README.md Shows how to implement the optional `persist/2` or `/3` function within the state machine module. This function is called after a successful transition and is responsible for saving the struct with the new state, typically to a database. It must return the updated struct. ```Elixir defmodule YourProject.UserStateMachine do alias YourProject.Accounts use Machinery, states: ["created", "completed"], transitions: %{"created" => "completed"} # You can add an optional third argument for the extra metadata. def persist(struct, next_state) do # Updating a user on the database with the new state. {:ok, user} = Accounts.update_user(struct, %{state: next_stated}) # `persist` should always return the updated struct user end end ``` -------------------------------- ### Adding Machinery Dependency in Elixir Source: https://github.com/joaomdmoura/machinery/blob/master/README.md Adds the `:machinery` library as a dependency in the `mix.exs` file, specifying the required version. This is the first step to include the library in an Elixir project. ```Elixir def deps do [ {:machinery, "~> 1.1.0"} ] end ``` -------------------------------- ### Adding State Field to Phoenix Model in Elixir Source: https://github.com/joaomdmoura/machinery/blob/master/README.md Demonstrates how to add a `:state` field of type `:string` to a Phoenix Ecto schema and include it in the `changeset/2` function to allow updates to the state field. ```Elixir defmodule YourProject.User do schema "users" do # ... field :state, :string # ... end def changeset(%User{} = user, attrs) do #... |> cast(attrs, [:state]) #... end end ``` -------------------------------- ### Result of Blocked Guarded Transition in Machinery (Elixir) Source: https://github.com/joaomdmoura/machinery/blob/master/README.md Illustrates the expected output when attempting to transition a struct that is blocked by a `guard_transition` callback. It shows the call to `Machinery.transition_to` and the resulting `{:error, "cause"}` tuple. ```Elixir blocked_struct = %TestStruct{state: "created", missing_fields: true} Machinery.transition_to(blocked_struct, TestStateMachineWithGuard, "completed") # {:error, "There are missing fields"} ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.