View Source Commanded.Projections.Ecto behaviour (commanded_ecto_projections v1.4.0)

Read model projections for Commanded using Ecto.

Example usage

defmodule Projector do
  use Commanded.Projections.Ecto,
    application: MyApp.Application,
    name: "my-projection",
    repo: MyApp.Repo,
    schema_prefix: "my-prefix",
    timeout: :infinity

  project %Event{}, _metadata, fn multi ->
    Ecto.Multi.insert(multi, :my_projection, %MyProjection{...})
  end

  project %AnotherEvent{}, fn multi ->
    Ecto.Multi.insert(multi, :my_projection, %MyProjection{...})
  end
end

Guides

Summary

Callbacks

The optional after_update/3 callback function defined in a projector is called after each projected event.

The optional schema_prefix/1 callback function defined in a projector is used to set the schema of the projection_versions table used by the projector for idempotency checks.

The optional schema_prefix/2 callback function defined in a projector is used to set the schema of the projection_versions table used by the projector for idempotency checks.

Functions

Project a domain event into a read model by appending one or more operations to the Ecto.Multi struct passed to the projection function you define

Project a domain event and its metadata map into a read model by appending one or more operations to the Ecto.Multi struct passed to the projection function you define.

Callbacks

Link to this callback

after_update(event, metadata, changes)

View Source (optional)
@callback after_update(
  event :: struct(),
  metadata :: map(),
  changes :: Ecto.Multi.changes()
) ::
  :ok | {:error, any()}

The optional after_update/3 callback function defined in a projector is called after each projected event.

The function receives the event, its metadata, and all changes from the Ecto.Multi struct that were executed within the database transaction.

You could use this function to notify subscribers that the read model has been updated, such as by publishing changes via Phoenix PubSub channels.

Example

defmodule MyApp.ExampleProjector do
  use Commanded.Projections.Ecto,
    application: MyApp.Application,
    repo: MyApp.Projections.Repo,
    name: "MyApp.ExampleProjector"

  project %AnEvent{name: name}, fn multi ->
    Ecto.Multi.insert(multi, :example_projection, %ExampleProjection{name: name})
  end

  @impl Commanded.Projections.Ecto
  def after_update(event, metadata, changes) do
    # Use the event, metadata, or `Ecto.Multi` changes and return `:ok`
    :ok
  end
end
Link to this callback

schema_prefix(event)

View Source (optional)
@callback schema_prefix(event :: struct()) :: String.t() | nil

The optional schema_prefix/1 callback function defined in a projector is used to set the schema of the projection_versions table used by the projector for idempotency checks.

It is passed the event and its metadata and must return the schema name, as a string, or nil.

Link to this callback

schema_prefix(event, metadata)

View Source (optional)
@callback schema_prefix(event :: struct(), metadata :: map()) :: String.t() | nil

The optional schema_prefix/2 callback function defined in a projector is used to set the schema of the projection_versions table used by the projector for idempotency checks.

It is passed the event and its metadata, and must return the schema name, as a string, or nil

Functions

Link to this macro

project(event, lambda)

View Source (macro)

Project a domain event into a read model by appending one or more operations to the Ecto.Multi struct passed to the projection function you define

The operations will be executed in a database transaction including an idempotency check to guarantee an event cannot be projected more than once.

Example

project %AnEvent{}, fn multi ->
  Ecto.Multi.insert(multi, :my_projection, %MyProjection{...})
end
Link to this macro

project(event, metadata, lambda)

View Source (macro)

Project a domain event and its metadata map into a read model by appending one or more operations to the Ecto.Multi struct passed to the projection function you define.

The operations will be executed in a database transaction including an idempotency check to guarantee an event cannot be projected more than once.

Example

project %AnEvent{}, metadata, fn multi ->
  Ecto.Multi.insert(multi, :my_projection, %MyProjection{...})
end