@@ -2147,13 +2147,15 @@ defmodule Ash.Actions.Update.Bulk do
21472147 end
21482148 end
21492149
2150- defp index_changesets_by_ref ( batch , context_key ) do
2151- Enum . reduce ( batch , % { } , fn changeset , changesets_by_ref ->
2152- Map . put (
2153- changesets_by_ref ,
2154- changeset . context [ context_key ] . ref ,
2155- changeset
2156- )
2150+ defp index_changesets ( batch , context_key ) do
2151+ Enum . reduce ( batch , { % { } , % { } } , fn changeset , { by_ref , by_index } ->
2152+ ref = changeset . context [ context_key ] . ref
2153+ index = changeset . context [ context_key ] . index
2154+
2155+ {
2156+ Map . put ( by_ref , ref , changeset ) ,
2157+ Map . put ( by_index , index , ref )
2158+ }
21572159 end )
21582160 end
21592161
@@ -2529,7 +2531,7 @@ defmodule Ash.Actions.Update.Bulk do
25292531 end
25302532 end )
25312533
2532- changesets_by_ref = index_changesets_by_ref ( batch , context_key )
2534+ { changesets_by_ref , changesets_by_index } = index_changesets ( batch , context_key )
25332535
25342536 batch =
25352537 batch
@@ -2686,7 +2688,7 @@ defmodule Ash.Actions.Update.Bulk do
26862688 end )
26872689 end
26882690
2689- { batch , changesets_by_ref }
2691+ { batch , changesets_by_ref , changesets_by_index }
26902692 end
26912693
26922694 defp manage_relationships ( updated , domain , changeset , engine_opts ) do
@@ -2704,7 +2706,7 @@ defmodule Ash.Actions.Update.Bulk do
27042706 end
27052707
27062708 defp run_after_action_hooks (
2707- { batch_results , changesets_by_ref } ,
2709+ { batch_results , changesets_by_ref , changesets_by_index } ,
27082710 opts ,
27092711 domain ,
27102712 ref ,
@@ -2759,11 +2761,11 @@ defmodule Ash.Actions.Update.Bulk do
27592761 end
27602762 end )
27612763
2762- { results , changesets_by_ref }
2764+ { results , changesets_by_ref , changesets_by_index }
27632765 end
27642766
27652767 defp process_results (
2766- { batch , changesets_by_ref } ,
2768+ { batch , changesets_by_ref , changesets_by_index } ,
27672769 changes ,
27682770 all_changes ,
27692771 opts ,
@@ -2780,6 +2782,7 @@ defmodule Ash.Actions.Update.Bulk do
27802782 all_changes ,
27812783 batch ,
27822784 changesets_by_ref ,
2785+ changesets_by_index ,
27832786 changesets ,
27842787 opts ,
27852788 ref ,
@@ -2872,6 +2875,7 @@ defmodule Ash.Actions.Update.Bulk do
28722875 all_changes ,
28732876 results ,
28742877 changesets_by_ref ,
2878+ changesets_by_index ,
28752879 changesets ,
28762880 opts ,
28772881 ref ,
@@ -2964,6 +2968,7 @@ defmodule Ash.Actions.Update.Bulk do
29642968 result ,
29652969 changes [ index ] ,
29662970 changesets_by_ref ,
2971+ changesets_by_index ,
29672972 metadata_key ,
29682973 ref_metadata_key
29692974 )
@@ -3573,17 +3578,39 @@ defmodule Ash.Actions.Update.Bulk do
35733578 changeset
35743579 end
35753580
3576- defp result_matches_changes? ( result , changes , changesets_by_ref , metadata_key , ref_metadata_key ) do
3577- if ref_metadata_key do
3581+ defp result_matches_changes? ( result , changes , changesets_by_ref , changesets_by_index , metadata_key , ref_metadata_key ) do
3582+ # For create/destroy operations, changesets_by_index may be nil and we use direct index matching
3583+ if is_nil ( changesets_by_index ) do
3584+ # Legacy behavior for create/destroy: direct index-based matching
3585+ result . __metadata__ [ metadata_key ] in List . wrap ( changes )
3586+ else
3587+ # New behavior for update operations: try ref first, then fallback to index->ref mapping
35783588 ref_key = result . __metadata__ [ ref_metadata_key ]
35793589
3580- changesets_by_ref
3581- |> Map . get ( ref_key )
3582- |> ensure_changeset! ( result , metadata_key , ref_metadata_key )
3590+ ref_key =
3591+ if ref_key do
3592+ ref_key
3593+ else
3594+ # Fallback: get ref from index mapping for backwards compatibility
3595+ index = result . __metadata__ [ metadata_key ]
35833596
3584- ref_key in List . wrap ( changes )
3585- else
3586- result . __metadata__ [ metadata_key ] in List . wrap ( changes )
3597+ if index do
3598+ changesets_by_index [ index ]
3599+ else
3600+ nil
3601+ end
3602+ end
3603+
3604+ if ref_key do
3605+ changesets_by_ref
3606+ |> Map . get ( ref_key )
3607+ |> ensure_changeset! ( result , metadata_key , ref_metadata_key )
3608+
3609+ ref_key in List . wrap ( changes )
3610+ else
3611+ # Final fallback to index-based matching if no ref available
3612+ result . __metadata__ [ metadata_key ] in List . wrap ( changes )
3613+ end
35873614 end
35883615 end
35893616
0 commit comments