Commanded v0.17.2 Commanded.Aggregate.Multi View Source

Use Commanded.Aggregate.Multi to generate multiple events from a single command.

This can be useful when you want to emit multiple events that depend upon the aggregate state being updated.

Example

In the example below, money is withdrawn from the bank account and the updated balance is used to check whether the account is overdrawn.

defmodule BankAccount do
  defstruct [
    account_number: nil,
    balance: 0,
    state: nil,
  ]

  alias Commanded.Aggregate.Multi

  def withdraw(
    %BankAccount{state: :active} = account,
    %WithdrawMoney{amount: amount})
    when is_number(amount) and amount > 0
  do
    account
    |> Multi.new()
    |> Multi.execute(&withdraw_money(&1, amount))
    |> Multi.execute(&check_balance/1)
  end

  defp withdraw_money(%BankAccount{account_number: account_number, balance: balance}, amount) do
    %MoneyWithdrawn{
      account_number: account_number,
      amount: amount,
      balance: balance - amount
    }
  end

  defp check_balance(%BankAccount{account_number: account_number, balance: balance})
    when balance < 0
  do
    %AccountOverdrawn{account_number: account_number, balance: balance}
  end
  defp check_balance(%BankAccount{}), do: []
end

Link to this section Summary

Functions

Adds a command execute function to the multi

Run the execute functions contained within the multi, returning the updated aggregate state and any created events

Link to this section Types

Link to this type t() View Source
t() :: %Commanded.Aggregate.Multi{aggregate: struct(), executions: [function()]}

Link to this section Functions

Adds a command execute function to the multi.

Create a new Commanded.Aggregate.Multi struct.

Link to this function run(multi) View Source
run(Commanded.Aggregate.Multi.t()) ::
  {aggregate :: struct(), [event :: struct()]} | {:error, reason :: any()}

Run the execute functions contained within the multi, returning the updated aggregate state and any created events.