mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 05:23:03 +12:00
fix: honor soft destroys for atomic bulk destroys
This commit is contained in:
parent
7b5a3267be
commit
701f9b4cc6
2 changed files with 142 additions and 69 deletions
|
@ -7,6 +7,61 @@ defmodule Ash.Actions.Destroy.Bulk do
|
|||
|
||||
def run(api, resource, action, input, opts, not_atomic_reason \\ nil)
|
||||
|
||||
def run(api, stream, action, input, opts, not_atomic_reason) when is_atom(action) do
|
||||
resource =
|
||||
opts[:resource] ||
|
||||
case stream do
|
||||
[%resource{} | _] ->
|
||||
resource
|
||||
|
||||
%Ash.Query{resource: resource} ->
|
||||
resource
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
|
||||
if !resource do
|
||||
raise ArgumentError,
|
||||
"Could not determine resource for bulk destroy. Please provide the `resource` option if providing a stream of inputs."
|
||||
end
|
||||
|
||||
run(api, stream, Ash.Resource.Info.action(resource, action), input, opts, not_atomic_reason)
|
||||
end
|
||||
|
||||
def run(api, stream, nil, input, opts, not_atomic_reason) do
|
||||
resource =
|
||||
opts[:resource] ||
|
||||
case stream do
|
||||
[%resource{} | _] ->
|
||||
resource
|
||||
|
||||
%Ash.Query{resource: resource} ->
|
||||
resource
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
|
||||
if !resource do
|
||||
raise ArgumentError,
|
||||
"Could not determine resource for bulk destroy. Please provide the `resource` option if providing a stream of inputs."
|
||||
end
|
||||
|
||||
run(
|
||||
api,
|
||||
stream,
|
||||
Ash.Resource.Info.primary_action!(resource, :destroy),
|
||||
input,
|
||||
opts,
|
||||
not_atomic_reason
|
||||
)
|
||||
end
|
||||
|
||||
def run(api, stream, %{soft?: true} = action, input, opts, not_atomic_reason) do
|
||||
Ash.Actions.Update.Bulk.run(api, stream, action, input, opts, not_atomic_reason)
|
||||
end
|
||||
|
||||
def run(api, resource, action, input, opts, not_atomic_reason) when is_atom(resource) do
|
||||
run(api, Ash.Query.new(resource), action, input, opts, not_atomic_reason)
|
||||
end
|
||||
|
@ -253,9 +308,6 @@ defmodule Ash.Actions.Destroy.Bulk do
|
|||
action
|
||||
end
|
||||
|
||||
if action.soft? do
|
||||
Ash.Actions.Update.Bulk.run(api, stream, action.name, input, opts)
|
||||
else
|
||||
if opts[:transaction] == :all && opts[:return_stream?] do
|
||||
raise ArgumentError,
|
||||
"Cannot specify `transaction: :all` and `return_stream?: true` together"
|
||||
|
@ -320,7 +372,6 @@ defmodule Ash.Actions.Destroy.Bulk do
|
|||
|> handle_bulk_result(resource, action, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp do_atomic_destroy(query, atomic_changeset, has_after_action_hooks?, input, opts) do
|
||||
atomic_changeset =
|
||||
|
|
|
@ -3,6 +3,7 @@ defmodule Ash.Test.Actions.BulkDestroyTest do
|
|||
use ExUnit.Case, async: true
|
||||
|
||||
require Ash.Query
|
||||
alias Ash.Test.AnyApi, as: Api
|
||||
|
||||
defmodule AddAfterToTitle do
|
||||
use Ash.Resource.Change
|
||||
|
@ -37,6 +38,7 @@ defmodule Ash.Test.Actions.BulkDestroyTest do
|
|||
defmodule Post do
|
||||
@moduledoc false
|
||||
use Ash.Resource,
|
||||
api: Api,
|
||||
data_layer: Ash.DataLayer.Ets,
|
||||
authorizers: [Ash.Policy.Authorizer]
|
||||
|
||||
|
@ -89,6 +91,11 @@ defmodule Ash.Test.Actions.BulkDestroyTest do
|
|||
|
||||
change set_context(%{authorize?: arg(:authorize?)})
|
||||
end
|
||||
|
||||
destroy :soft do
|
||||
soft? true
|
||||
change set_attribute(:title2, "archived")
|
||||
end
|
||||
end
|
||||
|
||||
identities do
|
||||
|
@ -117,15 +124,6 @@ defmodule Ash.Test.Actions.BulkDestroyTest do
|
|||
end
|
||||
end
|
||||
|
||||
defmodule Api do
|
||||
@moduledoc false
|
||||
use Ash.Api
|
||||
|
||||
resources do
|
||||
resource Post
|
||||
end
|
||||
end
|
||||
|
||||
test "returns destroyed records" do
|
||||
assert %Ash.BulkResult{records: [%{}, %{}]} =
|
||||
Api.bulk_create!([%{title: "title1"}, %{title: "title2"}], Post, :create,
|
||||
|
@ -313,6 +311,30 @@ defmodule Ash.Test.Actions.BulkDestroyTest do
|
|||
assert [] = Api.read!(Post)
|
||||
end
|
||||
|
||||
test "soft destroys" do
|
||||
assert %Ash.BulkResult{
|
||||
records: [
|
||||
%{title2: "archived"},
|
||||
%{title2: "archived"}
|
||||
]
|
||||
} =
|
||||
Api.bulk_create!([%{title: "title1"}, %{title: "title2"}], Post, :create,
|
||||
return_stream?: true,
|
||||
return_records?: true
|
||||
)
|
||||
|> Stream.map(fn {:ok, result} ->
|
||||
result
|
||||
end)
|
||||
|> Api.bulk_destroy!(:soft, %{},
|
||||
resource: Post,
|
||||
return_records?: true,
|
||||
return_errors?: true
|
||||
)
|
||||
|> Map.update!(:records, fn records ->
|
||||
Enum.sort_by(records, & &1.title)
|
||||
end)
|
||||
end
|
||||
|
||||
describe "authorization" do
|
||||
test "policy success results in successes" do
|
||||
assert %Ash.BulkResult{records: [_, _], errors: []} =
|
||||
|
|
Loading…
Reference in a new issue