Skip to content

Commit b2e4d62

Browse files
committed
fix: normalize bulk index metadata before returning
fixes #2392
1 parent 5617d4e commit b2e4d62

4 files changed

Lines changed: 42 additions & 0 deletions

File tree

lib/ash/actions/bulk_manual_action_helpers.ex

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ defmodule Ash.Actions.BulkManualActionHelpers do
207207
@doc """
208208
Finds the bulk operation index value from a record's metadata, searching through
209209
all possible namespaced metadata keys for the given bulk action type.
210+
Also supports the normalized simple format after metadata cleanup.
210211
"""
211212
def get_bulk_index(record, bulk_action_type \\ :bulk_update) do
212213
metadata_atom =
@@ -218,7 +219,10 @@ defmodule Ash.Actions.BulkManualActionHelpers do
218219

219220
record.__metadata__
220221
|> Enum.find_value(fn
222+
# Namespaced format (during processing)
221223
{{^metadata_atom, _ref}, index} -> index
224+
# Simple format (after normalization)
225+
{^metadata_atom, index} -> index
222226
_ -> nil
223227
end)
224228
end
@@ -258,4 +262,39 @@ defmodule Ash.Actions.BulkManualActionHelpers do
258262
{_, metadata_key} = extract_bulk_metadata(changeset, bulk_action_type)
259263
metadata_key
260264
end
265+
266+
@doc """
267+
Normalizes bulk operation metadata from the internal namespaced format to the simple public format.
268+
269+
This removes the reference-based keys like `{{:bulk_create_index, ref}, index}` and replaces them
270+
with simple keys like `{:bulk_create_index, index}` for cleaner public APIs.
271+
"""
272+
def normalize_record_metadata(record, bulk_action_type) when is_struct(record) do
273+
case get_bulk_index(record, bulk_action_type) do
274+
nil ->
275+
record
276+
277+
index ->
278+
metadata_atom =
279+
case bulk_action_type do
280+
:bulk_create -> :bulk_create_index
281+
:bulk_update -> :bulk_update_index
282+
:bulk_destroy -> :bulk_destroy_index
283+
end
284+
285+
# Remove the namespaced metadata key and add the simple one
286+
metadata =
287+
record.__metadata__
288+
|> Enum.reject(fn
289+
{{^metadata_atom, _ref}, _} -> true
290+
_ -> false
291+
end)
292+
|> Map.new()
293+
|> Map.put(metadata_atom, index)
294+
295+
%{record | __metadata__: metadata}
296+
end
297+
end
298+
299+
def normalize_record_metadata(other, _bulk_action_type), do: other
261300
end

lib/ash/actions/create/bulk.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,7 @@ defmodule Ash.Actions.Create.Bulk do
708708
action
709709
)
710710
|> Stream.concat(must_be_simple_results)
711+
|> Stream.map(&BulkManualActionHelpers.normalize_record_metadata(&1, :bulk_create))
711712
|> then(fn stream ->
712713
if opts[:return_stream?] do
713714
stream

lib/ash/actions/destroy/bulk.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,6 +1660,7 @@ defmodule Ash.Actions.Destroy.Bulk do
16601660
base_changeset
16611661
)
16621662
|> Stream.concat(must_be_simple_results)
1663+
|> Stream.map(&BulkManualActionHelpers.normalize_record_metadata(&1, :bulk_destroy))
16631664
|> then(fn stream ->
16641665
if opts[:return_stream?] do
16651666
stream

lib/ash/actions/update/bulk.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,6 +1969,7 @@ defmodule Ash.Actions.Update.Bulk do
19691969
domain,
19701970
base_changeset
19711971
)
1972+
|> Stream.map(&BulkManualActionHelpers.normalize_record_metadata(&1, :bulk_update))
19721973
|> then(fn stream ->
19731974
if opts[:return_stream?] do
19741975
stream

0 commit comments

Comments
 (0)