mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 13:33:20 +12:00
improvement: add get_and_lock/1
builtin change
This commit is contained in:
parent
2c8c8cafad
commit
7de83e8bb1
2 changed files with 44 additions and 0 deletions
|
@ -107,6 +107,22 @@ defmodule Ash.Resource.Change.Builtins do
|
|||
{Ash.Resource.Change.GetAndLockForUpdate, []}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Re-fetches the record being updated and locks it for update.
|
||||
|
||||
Only usable with data layers that support locking `:for_update`.
|
||||
|
||||
This happens in a `before_action` hook (so that it is done as part of the transaction).
|
||||
|
||||
If your resource has global validations (in the top level `validations` block), you may
|
||||
want to add `delay_global_validations? true` to your action to ensure they happen on the
|
||||
locked record.
|
||||
"""
|
||||
@spec get_and_lock(lock :: Ash.DataLayer.lock_type()) :: Ash.Resource.Change.ref()
|
||||
def get_and_lock(lock) do
|
||||
{Ash.Resource.Change.GetAndLock, [lock: lock]}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Sets the attribute to the value provided.
|
||||
|
||||
|
|
28
lib/ash/resource/change/get_and_lock.ex
Normal file
28
lib/ash/resource/change/get_and_lock.ex
Normal file
|
@ -0,0 +1,28 @@
|
|||
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
|
||||
|
||||
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 changeset.api.get(
|
||||
changeset.resource,
|
||||
pkey_values,
|
||||
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
|
||||
end
|
Loading…
Reference in a new issue