Skip to content

Commit 36706c5

Browse files
authored
fix: added bulk_action_ref for changeset lookups (#2411)
1 parent 3c883ef commit 36706c5

File tree

14 files changed

+597
-125
lines changed

14 files changed

+597
-125
lines changed

lib/ash/action_input.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ defmodule Ash.ActionInput do
9898
resource: Ash.Resource.t(),
9999
invalid_keys: MapSet.t(),
100100
context: map(),
101-
domain: Ash.Domain.t(),
101+
domain: Ash.Domain.t() | nil,
102102
valid?: boolean(),
103103
errors: [Ash.Error.t()],
104104
before_action: [before_action_fun],
@@ -132,7 +132,7 @@ defmodule Ash.ActionInput do
132132
- `set_argument/3` for adding arguments
133133
- `set_context/2` for adding context
134134
"""
135-
@spec new(Ash.Resource.t(), Ash.Domain.t()) :: t
135+
@spec new(Ash.Resource.t(), Ash.Domain.t() | nil) :: t
136136
def new(resource, domain \\ nil) do
137137
%__MODULE__{resource: resource, domain: domain}
138138
end

lib/ash/actions/bulk_manual_action_helpers.ex

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,21 +87,29 @@ defmodule Ash.Actions.BulkManualActionHelpers do
8787
case result do
8888
{:ok, record} ->
8989
record =
90-
Ash.Resource.put_metadata(
91-
record,
90+
record
91+
|> Ash.Resource.put_metadata(
9292
metadata_index_name,
9393
changeset.context[bulk_action_type].index
9494
)
95+
|> Ash.Resource.put_metadata(
96+
:bulk_action_ref,
97+
changeset.context[bulk_action_type].ref
98+
)
9599

96100
{:ok, record}
97101

98102
{:ok, record, notifications} ->
99103
record =
100-
Ash.Resource.put_metadata(
101-
record,
104+
record
105+
|> Ash.Resource.put_metadata(
102106
metadata_index_name,
103107
changeset.context[bulk_action_type].index
104108
)
109+
|> Ash.Resource.put_metadata(
110+
:bulk_action_ref,
111+
changeset.context[bulk_action_type].ref
112+
)
105113

106114
{:ok, record, notifications}
107115

lib/ash/actions/create/bulk.ex

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ defmodule Ash.Actions.Create.Bulk do
669669
:bulk_create
670670
)
671671

672-
changesets_by_index = index_changesets(batch)
672+
{changesets_by_ref, changesets_by_index} = index_changesets(batch)
673673

674674
run_batch(
675675
resource,
@@ -683,6 +683,7 @@ defmodule Ash.Actions.Create.Bulk do
683683
ref,
684684
attrs_to_require,
685685
action_select,
686+
changesets_by_ref,
686687
changesets_by_index
687688
)
688689
|> run_after_action_hooks(opts, domain, ref)
@@ -691,6 +692,7 @@ defmodule Ash.Actions.Create.Bulk do
691692
all_changes,
692693
opts,
693694
ref,
695+
changesets_by_ref,
694696
changesets_by_index,
695697
batch,
696698
domain,
@@ -720,7 +722,7 @@ defmodule Ash.Actions.Create.Bulk do
720722
argument_names
721723
) do
722724
base
723-
|> Ash.Changeset.put_context(:bulk_create, %{index: index})
725+
|> Ash.Changeset.put_context(:bulk_create, %{index: index, ref: make_ref()})
724726
|> Ash.Changeset.set_private_arguments_for_action(opts[:private_arguments] || %{})
725727
|> handle_params(
726728
Keyword.get(opts, :assume_casted?, false),
@@ -868,12 +870,14 @@ defmodule Ash.Actions.Create.Bulk do
868870
end
869871

870872
defp index_changesets(batch) do
871-
Enum.reduce(batch, %{}, fn changeset, changesets_by_index ->
872-
Map.put(
873-
changesets_by_index,
874-
changeset.context.bulk_create.index,
875-
changeset
876-
)
873+
Enum.reduce(batch, {%{}, %{}}, fn changeset, {by_ref, by_index} ->
874+
ref = changeset.context.bulk_create.ref
875+
index = changeset.context.bulk_create.index
876+
877+
{
878+
Map.put(by_ref, ref, changeset),
879+
Map.put(by_index, index, ref)
880+
}
877881
end)
878882
end
879883

@@ -1031,6 +1035,7 @@ defmodule Ash.Actions.Create.Bulk do
10311035
ref,
10321036
attrs_to_require,
10331037
action_select,
1038+
changesets_by_ref,
10341039
changesets_by_index
10351040
) do
10361041
batch
@@ -1092,7 +1097,7 @@ defmodule Ash.Actions.Create.Bulk do
10921097
end)
10931098
|> case do
10941099
[] ->
1095-
{[], changesets_by_index}
1100+
{[], changesets_by_ref, changesets_by_index}
10961101

10971102
batch ->
10981103
upsert_keys =
@@ -1122,7 +1127,7 @@ defmodule Ash.Actions.Create.Bulk do
11221127
end
11231128
end
11241129

1125-
changesets_by_index = index_changesets(batch)
1130+
{changesets_by_ref, changesets_by_index} = index_changesets(batch)
11261131

11271132
batch
11281133
|> Enum.group_by(&{&1.atomics, &1.filter})
@@ -1346,7 +1351,7 @@ defmodule Ash.Actions.Create.Bulk do
13461351
[]
13471352
end
13481353
end)
1349-
|> then(&{&1, changesets_by_index})
1354+
|> then(&{&1, changesets_by_ref, changesets_by_index})
13501355
end
13511356
end
13521357

@@ -1365,13 +1370,20 @@ defmodule Ash.Actions.Create.Bulk do
13651370
end
13661371

13671372
defp run_after_action_hooks(
1368-
{batch_results, changesets_by_index},
1373+
{batch_results, changesets_by_ref, changesets_by_index},
13691374
opts,
13701375
domain,
13711376
ref
13721377
) do
13731378
Enum.flat_map(batch_results, fn result ->
1374-
changeset = changesets_by_index[result.__metadata__.bulk_create_index]
1379+
changeset =
1380+
Ash.Actions.Helpers.lookup_changeset(
1381+
result,
1382+
changesets_by_ref,
1383+
changesets_by_index,
1384+
index_key: :bulk_create_index,
1385+
ref_key: :bulk_action_ref
1386+
)
13751387

13761388
case manage_relationships(result, domain, changeset,
13771389
upsert?: opts[:upsert?],
@@ -1413,6 +1425,7 @@ defmodule Ash.Actions.Create.Bulk do
14131425
all_changes,
14141426
opts,
14151427
ref,
1428+
changesets_by_ref,
14161429
changesets_by_index,
14171430
changesets,
14181431
domain,
@@ -1422,7 +1435,14 @@ defmodule Ash.Actions.Create.Bulk do
14221435
) do
14231436
results =
14241437
Enum.flat_map(batch, fn result ->
1425-
changeset = changesets_by_index[result.__metadata__.bulk_create_index]
1438+
changeset =
1439+
Ash.Actions.Helpers.lookup_changeset(
1440+
result,
1441+
changesets_by_ref,
1442+
changesets_by_index,
1443+
index_key: :bulk_create_index,
1444+
ref_key: :bulk_action_ref
1445+
)
14261446

14271447
if opts[:notify?] || opts[:return_notifications?] do
14281448
store_notification(ref, notification(changeset, result, opts), opts)
@@ -1455,12 +1475,14 @@ defmodule Ash.Actions.Create.Bulk do
14551475
|> Ash.Actions.Update.Bulk.run_bulk_after_changes(
14561476
all_changes,
14571477
results,
1478+
changesets_by_ref,
14581479
changesets_by_index,
14591480
changesets,
14601481
opts,
14611482
ref,
14621483
resource,
1463-
:bulk_create_index
1484+
:bulk_create_index,
1485+
:bulk_action_ref
14641486
)
14651487
|> then(fn records ->
14661488
if opts[:return_records?] do

lib/ash/actions/destroy/bulk.ex

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,7 +1472,8 @@ defmodule Ash.Actions.Destroy.Bulk do
14721472

14731473
[
14741474
Ash.Resource.set_metadata(result, %{
1475-
bulk_destroy_index: changeset.context.bulk_destroy.index
1475+
bulk_destroy_index: changeset.context.bulk_destroy.index,
1476+
bulk_action_ref: changeset.context.bulk_destroy.ref
14761477
})
14771478
]
14781479

@@ -1490,7 +1491,8 @@ defmodule Ash.Actions.Destroy.Bulk do
14901491

14911492
[
14921493
Ash.Resource.set_metadata(result, %{
1493-
bulk_destroy_index: changeset.context.bulk_destroy.index
1494+
bulk_destroy_index: changeset.context.bulk_destroy.index,
1495+
bulk_action_ref: changeset.context.bulk_destroy.ref
14941496
})
14951497
]
14961498

@@ -1628,7 +1630,7 @@ defmodule Ash.Actions.Destroy.Bulk do
16281630
:bulk_destroy
16291631
)
16301632

1631-
changesets_by_index = index_changesets(batch)
1633+
{changesets_by_ref, changesets_by_index} = index_changesets(batch)
16321634

16331635
run_batch(
16341636
resource,
@@ -1640,12 +1642,13 @@ defmodule Ash.Actions.Destroy.Bulk do
16401642
domain,
16411643
ref
16421644
)
1643-
|> run_after_action_hooks(opts, domain, ref, changesets_by_index)
1645+
|> run_after_action_hooks(opts, domain, ref, changesets_by_ref, changesets_by_index)
16441646
|> process_results(
16451647
changes,
16461648
all_changes,
16471649
opts,
16481650
ref,
1651+
changesets_by_ref,
16491652
changesets_by_index,
16501653
batch,
16511654
domain,
@@ -1678,7 +1681,7 @@ defmodule Ash.Actions.Destroy.Bulk do
16781681
|> Map.put(:domain, domain)
16791682
|> Ash.Changeset.prepare_changeset_for_action(action, opts)
16801683
|> Ash.Changeset.set_private_arguments_for_action(opts[:private_arguments] || %{})
1681-
|> Ash.Changeset.put_context(:bulk_destroy, %{index: index})
1684+
|> Ash.Changeset.put_context(:bulk_destroy, %{index: index, ref: make_ref()})
16821685
|> Ash.Changeset.set_context(opts[:context] || %{})
16831686
|> handle_params(
16841687
Keyword.get(opts, :assume_casted?, false),
@@ -1769,12 +1772,14 @@ defmodule Ash.Actions.Destroy.Bulk do
17691772
end
17701773

17711774
defp index_changesets(batch) do
1772-
Enum.reduce(batch, %{}, fn changeset, changesets_by_index ->
1773-
Map.put(
1774-
changesets_by_index,
1775-
changeset.context.bulk_destroy.index,
1776-
changeset
1777-
)
1775+
Enum.reduce(batch, {%{}, %{}}, fn changeset, {by_ref, by_index} ->
1776+
ref = changeset.context.bulk_destroy.ref
1777+
index = changeset.context.bulk_destroy.index
1778+
1779+
{
1780+
Map.put(by_ref, ref, changeset),
1781+
Map.put(by_index, index, ref)
1782+
}
17781783
end)
17791784
end
17801785

@@ -2072,6 +2077,10 @@ defmodule Ash.Actions.Destroy.Bulk do
20722077
:bulk_destroy_index,
20732078
changeset.context.bulk_destroy.index
20742079
)
2080+
|> Ash.Resource.put_metadata(
2081+
:bulk_action_ref,
2082+
changeset.context.bulk_destroy.ref
2083+
)
20752084
]}
20762085

20772086
{:error, error} ->
@@ -2116,10 +2125,18 @@ defmodule Ash.Actions.Destroy.Bulk do
21162125
opts,
21172126
domain,
21182127
ref,
2128+
changesets_by_ref,
21192129
changesets_by_index
21202130
) do
21212131
Enum.flat_map(batch_results, fn result ->
2122-
changeset = changesets_by_index[result.__metadata__.bulk_destroy_index]
2132+
changeset =
2133+
Ash.Actions.Helpers.lookup_changeset(
2134+
result,
2135+
changesets_by_ref,
2136+
changesets_by_index,
2137+
index_key: :bulk_destroy_index,
2138+
ref_key: :bulk_action_ref
2139+
)
21232140

21242141
case manage_relationships(result, domain, changeset,
21252142
actor: opts[:actor],
@@ -2160,6 +2177,7 @@ defmodule Ash.Actions.Destroy.Bulk do
21602177
all_changes,
21612178
opts,
21622179
ref,
2180+
changesets_by_ref,
21632181
changesets_by_index,
21642182
changesets,
21652183
domain,
@@ -2170,15 +2188,24 @@ defmodule Ash.Actions.Destroy.Bulk do
21702188
|> Ash.Actions.Update.Bulk.run_bulk_after_changes(
21712189
all_changes,
21722190
batch,
2191+
changesets_by_ref,
21732192
changesets_by_index,
21742193
changesets,
21752194
opts,
21762195
ref,
21772196
resource,
2178-
:bulk_destroy_index
2197+
:bulk_destroy_index,
2198+
:bulk_action_ref
21792199
)
21802200
|> Enum.flat_map(fn result ->
2181-
changeset = changesets_by_index[result.__metadata__[:bulk_destroy_index]]
2201+
changeset =
2202+
Ash.Actions.Helpers.lookup_changeset(
2203+
result,
2204+
changesets_by_ref,
2205+
changesets_by_index,
2206+
index_key: :bulk_destroy_index,
2207+
ref_key: :bulk_action_ref
2208+
)
21822209

21832210
if opts[:notify?] || opts[:return_notifications?] do
21842211
store_notification(ref, notification(changeset, result, opts), opts)

0 commit comments

Comments
 (0)