AshCommanded.Commanded.Transformers.GenerateAggregateModule (AshCommanded v0.1.0)
View SourceGenerates an aggregate module based on the commands and events defined in the DSL.
For each resource, this transformer will generate an aggregate module that:
- Defines a struct representing the aggregate state
- Implements the
execute/2
function for handling commands - Implements the
apply/2
function for applying events to the state
This transformer should run after the command and event module transformers.
Example
Given a resource with commands and events, this transformer will generate:
defmodule MyApp.UserAggregate do
@moduledoc "Aggregate for User resource"
# Define the aggregate state struct
defstruct [:id, :email, :name, :status]
# Command handlers
def execute(%__MODULE__{} = aggregate, %MyApp.Commands.RegisterUser{} = command) do
# Validate command - in this case, prevent duplicate registration
if aggregate.id != nil do
{:error, :user_already_registered}
else
# Return event(s) to be applied
{:ok, %MyApp.Events.UserRegistered{
id: command.id,
email: command.email,
name: command.name
}}
end
end
def execute(%__MODULE__{} = aggregate, %MyApp.Commands.UpdateEmail{} = command) do
# Validate command - only allow updating existing user
if aggregate.id == nil do
{:error, :user_not_found}
else
# Return event(s) to be applied
{:ok, %MyApp.Events.EmailChanged{
id: command.id,
email: command.email
}}
end
end
# Event handlers to update state
def apply(%__MODULE__{} = state, %MyApp.Events.UserRegistered{} = event) do
%__MODULE__{
state |
id: event.id,
email: event.email,
name: event.name,
status: :active
}
end
def apply(%__MODULE__{} = state, %MyApp.Events.EmailChanged{} = event) do
%__MODULE__{
state |
email: event.email
}
end
end
Summary
Functions
Specifies that this transformer should run after the command and event module transformers.
Callback implementation for Spark.Dsl.Transformer.after_compile?/0
.
Callback implementation for Spark.Dsl.Transformer.before?/1
.
Builds the module name for an aggregate.
Builds the AST (Abstract Syntax Tree) for an aggregate module.
Transforms the DSL state to generate an aggregate module.
Functions
Specifies that this transformer should run after the command and event module transformers.
Callback implementation for Spark.Dsl.Transformer.after_compile?/0
.
Callback implementation for Spark.Dsl.Transformer.before?/1
.
Builds the module name for an aggregate.
Examples
iex> build_aggregate_module("User", MyApp)
MyApp.UserAggregate
Builds the AST (Abstract Syntax Tree) for an aggregate module.
Examples
iex> build_aggregate_module_ast("User", attribute_names, commands, events, command_modules, event_modules)
{:__block__, [], [{:@, [...], [{:moduledoc, [...], [...]}]}, ...]}
Transforms the DSL state to generate an aggregate module.
Examples
iex> transform(dsl_state)
{:ok, updated_dsl_state}