defmodule Ash.Resource.Change.GetAndLock do
@moduledoc """
Refetches the record being updated or destroyed, and locks it with the given type.
"""
use Ash.Resource.Change
@impl true
def change(changeset, opts, context) do
Ash.Changeset.before_action(changeset, fn changeset ->
primary_key = Ash.Resource.Info.primary_key(changeset.resource)
pkey_values = changeset.data |> Map.take(primary_key) |> Map.to_list()
case Ash.get(
changeset.resource,
pkey_values,
domain: changeset.domain,
tracer: context.tracer,
tenant: context.tenant,
authorize?: false,
lock: opts[:lock]
) do
{:ok, record} ->
%{changeset | data: record}
{:error, error} ->
Ash.Changeset.add_error(changeset, error)
end
end)
end
@impl true
def atomic(_changeset, opts, _) do
if opts[:skip_atomic?] do
:ok
else
{:not_atomic,
"""
Cannot lock during an atomic update. If no lock is necessary in an atomic situation,
add `skip_atomic_?: true`, i.e `change get_and_lock(#{opts[:lock]}, skip_atomic?: true)`
"""}
end
end
end