Search documentation of ash

# Ash.Resource.Change behaviour (ash v3.4.71)

View Source

The behaviour for an action-specific resource change.

`init/1` is defined automatically by `use Ash.Resource.Change`, but can be implemented if you want to validate/transform any options passed to the module.

The main function is `change/3`. It takes the changeset, any options that were provided when this change was configured on a resource, and the context, which currently only has the actor.

# Summary

## Types

context()
ref()
t()

## Callbacks

after_batch(changesets_and_results, opts, context)

Runs on each batch result after it is dispatched to the data layer.

atomic(changeset, opts, context)
atomic?()
batch_callbacks?(changesets_or_query, opts, context)

Whether or not batch callbacks should be run (if they are defined). Defaults to `true`.

batch_change(changesets, opts, context)

Replaces `change/3` for batch actions, allowing to optimize changes for bulk actions.

before_batch(changesets, opts, context)

Runs on each batch before it is dispatched to the data layer.

change(changeset, opts, context)
has_after_batch?()
has_batch_change?()
has_before_batch?()
has_change?()
init(opts)

# Types

# context()

    @type context() :: Ash.Resource.Change.Context.t()

# ref()

    @type ref() :: {module(), Keyword.t()} | module()

# t()

    @type t() :: %Ash.Resource.Change{
      always_atomic?: term(),
      change: term(),
      description: term(),
      on: term(),
      only_when_valid?: term(),
      where: term()
    }

# Callbacks

# after_batch(changesets_and_results, opts, context)

(optional)

    @callback after_batch(
      changesets_and_results :: [{Ash.Changeset.t(), Ash.Resource.record()}],
      opts :: Keyword.t(),
      context :: Ash.Resource.Change.Context.t()
    ) ::
      :ok
      | Enumerable.t(
          {:ok, Ash.Resource.record()}
          | {:error, Ash.Error.t()}
          | Ash.Notifier.Notification.t()
        )

Runs on each batch result after it is dispatched to the data layer.

# atomic(changeset, opts, context)

(optional)

    @callback atomic(
      changeset :: Ash.Changeset.t(),
      opts :: Keyword.t(),
      context :: Ash.Resource.Change.Context.t()
    ) ::
      {:ok, Ash.Changeset.t()}
      | {:atomic, %{optional(atom()) => Ash.Expr.t() | {:atomic, Ash.Expr.t()}}}
      | {:atomic, Ash.Changeset.t(), %{optional(atom()) => Ash.Expr.t()}}
      | {:atomic, Ash.Changeset.t(), %{optional(atom()) => Ash.Expr.t()},
         [
           {:atomic, involved_fields :: [atom()] | :*,
            condition_expr :: Ash.Expr.t(), error_expr :: Ash.Expr.t()}
         ]}
      | {:atomic, %{optional(atom()) => Ash.Expr.t()},
         [
           {:atomic, involved_fields :: [atom()] | :*,
            condition_expr :: Ash.Expr.t(), error_expr :: Ash.Expr.t()}
         ]}
      | {:not_atomic, String.t()}
      | :ok
      | {:error, term()}

# atomic?()

    @callback atomic?() :: boolean()

# batch_callbacks?(changesets_or_query, opts, context)

    @callback batch_callbacks?(
      changesets_or_query :: [Ash.Changeset.t()] | Ash.Query.t(),
      opts :: Keyword.t(),
      context :: Ash.Resource.Change.Context.t()
    ) :: boolean()

Whether or not batch callbacks should be run (if they are defined). Defaults to `true`.

# batch_change(changesets, opts, context)

(optional)

    @callback batch_change(
      changesets :: [Ash.Changeset.t()],
      opts :: Keyword.t(),
      context :: Ash.Resource.Change.Context.t()
    ) :: Enumerable.t(Ash.Changeset.t())

Replaces `change/3` for batch actions, allowing to optimize changes for bulk actions.

You can define only `batch_change/3`, and it will be used for both single and batch actions. It cannot, however, be used in place of the `atomic/3` callback.

# before_batch(changesets, opts, context)

(optional)

    @callback before_batch(
      changesets :: [Ash.Changeset.t()],
      opts :: Keyword.t(),
      context :: Ash.Resource.Change.Context.t()
    ) :: Enumerable.t(Ash.Changeset.t() | Ash.Notifier.Notification.t())

Runs on each batch before it is dispatched to the data layer.

# change(changeset, opts, context)

(optional)

    @callback change(
      changeset :: Ash.Changeset.t(),
      opts :: Keyword.t(),
      context :: Ash.Resource.Change.Context.t()
    ) :: Ash.Changeset.t()

# has_after_batch?()

    @callback has_after_batch?() :: boolean()

# has_batch_change?()

    @callback has_batch_change?() :: boolean()

# has_before_batch?()

    @callback has_before_batch?() :: boolean()

# has_change?()

    @callback has_change?() :: boolean()

# init(opts)

    @callback init(opts :: Keyword.t()) :: {:ok, Keyword.t()} | {:error, term()}