ex_workflow v0.1.0 ExWorkflow

A minimal workflow implementation for Ecto schemas. Inspired by Ruby's geekq/workflow.

Usage

By importing ExWorkflow into your Ecto schema module, you can define your workflow in the format of

workflow do
  state ~> event ~> new_state
  ...
end

The default state field is state. If you want to use a custom field to store the states, you can pass state_field: <custom state field name> to the workflow macro:

workflow state_field: :my_state do
  ...
end

Example

defmodule Article do
  use Ecto.Schema
  import ExWorkflow
  import Ecto.Changeset

  schema "articles" do
    field :state, :string
  end

  workflow do
    # state ~> event ~> new_state
    "unpublished" ~> :publish ~> "published"
    "published" ~> :unpublish ~> "unpublished"
    "unpublished" ~> :trash ~> "trashed_unpublished"
    "published" ~> :trash ~> "trashed_published"
    "trashed_unpublished" ~> :recycle ~> "unpublished"
    "trashed_published" ~> :recycle ~> "published"
  end

  # You can override the event :publish. It should return a changeset.
  # The `super` keyword is also available.
  def publish(changeset) do
    # Do something interesting
    super(changeset)
  end

  # You can also pass 1 additional argument of any type.
  def publish(changeset, discard_draft: true) do
    ...
  end
end

Each event gives 2 functions named after the event, for example, the :publish event, gives publish(changeset) and publish(changeset, addtional_arg). The additional argument is by default ignored, but you can override it.

changeset = %Article{} 
            |> Ecto.Changeset.cast(%Article{state: "unpublished"}, %{}, [:state])
            |> Article.publish()

Ecto.Changeset.get_field(changeset, :state)  #=> "published"

changeset = Article.trash(changeset)
Ecto.Changeset.get_field(changeset, :state)  #=> "trashed_published"

changeset = Article.recycle(changeset)
Ecto.Changeset.get_field(changeset, :state)  #=> "published"

TODO

  • Workflow specification API
  • Draw workflow diagram

Link to this section Summary

Link to this section Functions

Link to this macro

workflow(list)

(macro)