mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 05:23:03 +12:00
improvement: properly handle after_action hooks in fully atomic changesets
This commit is contained in:
parent
78114226a6
commit
9421dbe535
1 changed files with 34 additions and 5 deletions
|
@ -44,9 +44,9 @@ defmodule Ash.Actions.Update.Bulk do
|
||||||
|
|
||||||
fully_atomic_changeset =
|
fully_atomic_changeset =
|
||||||
cond do
|
cond do
|
||||||
!Enum.empty?(query.before_action) || !Enum.empty?(query.after_action) ->
|
!Enum.empty?(query.before_action) ->
|
||||||
{:not_atomic,
|
{:not_atomic,
|
||||||
"cannot atomically update a query if it has `before_action` or `after_action` hooks"}
|
"cannot atomically update a query if it has `before_action` hooks"}
|
||||||
|
|
||||||
not_atomic_reason ->
|
not_atomic_reason ->
|
||||||
{:not_atomic, not_atomic_reason}
|
{:not_atomic, not_atomic_reason}
|
||||||
|
@ -195,7 +195,7 @@ defmodule Ash.Actions.Update.Bulk do
|
||||||
# having after action hooks. Or perhaps we need to stream the ids and then bulk update
|
# having after action hooks. Or perhaps we need to stream the ids and then bulk update
|
||||||
# them.
|
# them.
|
||||||
opts =
|
opts =
|
||||||
if has_after_batch_hooks? || opts[:notify?] do
|
if has_after_batch_hooks? || !Enum.empty?(atomic_changeset.after_action) || opts[:notify?] do
|
||||||
Keyword.put(opts, :return_records?, true)
|
Keyword.put(opts, :return_records?, true)
|
||||||
else
|
else
|
||||||
opts
|
opts
|
||||||
|
@ -465,6 +465,8 @@ defmodule Ash.Actions.Update.Bulk do
|
||||||
|
|
||||||
results = List.wrap(results)
|
results = List.wrap(results)
|
||||||
|
|
||||||
|
IO.inspect(atomic_changeset.after_action, label: "THE HOOKS DUDE!")
|
||||||
|
|
||||||
{results, notifications} =
|
{results, notifications} =
|
||||||
if has_after_batch_hooks? do
|
if has_after_batch_hooks? do
|
||||||
run_atomic_after_batch_hooks(
|
run_atomic_after_batch_hooks(
|
||||||
|
@ -478,6 +480,33 @@ defmodule Ash.Actions.Update.Bulk do
|
||||||
{results, []}
|
{results, []}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
{results, errors, error_count, notifications} =
|
||||||
|
if Enum.empty?(atomic_changeset.after_action) do
|
||||||
|
{results, [], 0, notifications}
|
||||||
|
else
|
||||||
|
Enum.reduce(results, {[], [], 0, notifications}, fn result, {results, errors, error_count, notifications} ->
|
||||||
|
case Ash.Changeset.run_after_actions(result, atomic_changeset, []) do
|
||||||
|
{:error, error} ->
|
||||||
|
if opts[:transaction] && opts[:rollback_on_error?] do
|
||||||
|
if Ash.DataLayer.in_transaction?(atomic_changeset.resource) do
|
||||||
|
Ash.DataLayer.rollback(
|
||||||
|
atomic_changeset.resource,
|
||||||
|
error
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
{results, errors ++ List.wrap(error), error_count + Enum.count(List.wrap(error)), notifications}
|
||||||
|
|
||||||
|
{:ok, result, _changeset, %{notifications: more_new_notifications}} ->
|
||||||
|
{[result | results], errors, error_count, notifications ++ more_new_notifications}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|> then(fn {results, errors, error_count, notifications} ->
|
||||||
|
{Enum.reverse(results), errors, error_count, notifications}
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
{results, errors, error_count} =
|
{results, errors, error_count} =
|
||||||
case load_data(
|
case load_data(
|
||||||
results,
|
results,
|
||||||
|
@ -487,10 +516,10 @@ defmodule Ash.Actions.Update.Bulk do
|
||||||
opts
|
opts
|
||||||
) do
|
) do
|
||||||
{:ok, results} ->
|
{:ok, results} ->
|
||||||
{results, [], 0}
|
{results, errors, error_count}
|
||||||
|
|
||||||
{:error, error} ->
|
{:error, error} ->
|
||||||
{[], List.wrap(error), Enum.count(List.wrap(error))}
|
{[], errors ++ List.wrap(error), error_count + Enum.count(List.wrap(error))}
|
||||||
end
|
end
|
||||||
|
|
||||||
notifications =
|
notifications =
|
||||||
|
|
Loading…
Reference in a new issue