Skip to content

Commit c3e3d7c

Browse files
authored
fix: call manage_relationships in single hard destroy path (#2596)
The single hard destroy path in `destroy.ex` never called `manage_relationships`, causing any `manage_relationship` changes declared on hard destroy actions to be silently ignored. The bulk destroy, soft destroy, create, and update paths all properly called `manage_relationships`. Adds `manage_relationships/4` to `Ash.Actions.Destroy` following the same pattern used in `Ash.Actions.Update`, and pipes the data layer result through it before the notification/select pipeline. Also adds comprehensive tests for manage_relationship on destroy actions: single hard destroy, single soft destroy, bulk hard destroy, and bulk soft destroy. Closes ash-project/ash_postgres#702
1 parent 3edbaee commit c3e3d7c

File tree

4 files changed

+432
-3
lines changed

4 files changed

+432
-3
lines changed

lib/ash/actions/destroy/destroy.ex

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,11 +242,15 @@ defmodule Ash.Actions.Destroy do
242242
end
243243
end
244244
end
245+
|> manage_relationships(domain, changeset,
246+
actor: opts[:actor],
247+
authorize?: opts[:authorize?]
248+
)
245249
|> then(fn result ->
246250
case result do
247-
{:ok, destroyed} ->
251+
{:ok, destroyed, %{notifications: manage_notifications}} ->
248252
if opts[:return_destroyed?] do
249-
{:ok, destroyed, %{notifications: []}}
253+
{:ok, destroyed, %{notifications: manage_notifications}}
250254
|> Helpers.notify(changeset, opts)
251255
|> Helpers.select(changeset)
252256
|> Helpers.restrict_field_access(changeset)
@@ -257,7 +261,7 @@ defmodule Ash.Actions.Destroy do
257261
select: changeset.action_select
258262
})
259263

260-
{:ok, destroyed, %{notifications: []}}
264+
{:ok, destroyed, %{notifications: manage_notifications}}
261265
|> Helpers.notify(changeset, opts)
262266
end
263267

@@ -304,6 +308,37 @@ defmodule Ash.Actions.Destroy do
304308
end
305309
end
306310

311+
defp manage_relationships(
312+
{:ok, destroyed, %{notifications: notifications}},
313+
domain,
314+
changeset,
315+
engine_opts
316+
) do
317+
case manage_relationships({:ok, destroyed}, domain, changeset, engine_opts) do
318+
{:ok, destroyed, info} ->
319+
{:ok, destroyed, Map.update(info, :notifications, notifications, &(&1 ++ notifications))}
320+
321+
other ->
322+
other
323+
end
324+
end
325+
326+
defp manage_relationships({:ok, destroyed}, domain, changeset, engine_opts) do
327+
with {:ok, loaded} <-
328+
Ash.Actions.ManagedRelationships.load(domain, destroyed, changeset, engine_opts),
329+
{:ok, with_relationships, new_notifications} <-
330+
Ash.Actions.ManagedRelationships.manage_relationships(
331+
loaded,
332+
changeset,
333+
engine_opts[:actor],
334+
engine_opts
335+
) do
336+
{:ok, with_relationships, %{notifications: new_notifications}}
337+
end
338+
end
339+
340+
defp manage_relationships(other, _, _, _), do: other
341+
307342
defp set_tenant(changeset) do
308343
changeset =
309344
case changeset.data do

lib/ash/error/unknown/invalid_casted_value.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# SPDX-FileCopyrightText: 2019 ash contributors <https://github.com/ash-project/ash/graphs/contributors>
2+
#
3+
# SPDX-License-Identifier: MIT
4+
15
defmodule Ash.Error.Unknown.InvalidCastedValue do
26
@moduledoc "Used when a value fails to dump to its native (storage) format"
37

lib/ash/error/unknown/invalid_stored_value.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# SPDX-FileCopyrightText: 2019 ash contributors <https://github.com/ash-project/ash/graphs/contributors>
2+
#
3+
# SPDX-License-Identifier: MIT
4+
15
defmodule Ash.Error.Unknown.InvalidStoredValue do
26
@moduledoc "Used when a stored value fails to be cast from the data layer"
37

0 commit comments

Comments
 (0)