@@ -2120,35 +2120,63 @@ defmodule AshPostgres.DataLayer do
21202120 { Map . take ( r , keys ) , r }
21212121 end )
21222122
2123- results =
2124- changesets
2125- |> Enum . map ( fn changeset ->
2126- identity =
2127- changeset . attributes
2128- |> Map . take ( keys )
2123+ cant_map_results_to_changesets =
2124+ any_generated_keys_missing? ( keys , resource , changesets )
21292125
2130- result_for_changeset = Map . get ( results_by_identity , identity )
2131-
2132- if result_for_changeset do
2126+ results =
2127+ if cant_map_results_to_changesets do
2128+ results
2129+ |> Enum . zip ( changesets )
2130+ |> Enum . map ( fn { result , changeset } ->
21332131 if ! opts [ :upsert? ] do
2134- maybe_create_tenant! ( resource , result_for_changeset )
2132+ maybe_create_tenant! ( resource , result )
21352133 end
21362134
21372135 case get_bulk_operation_metadata ( changeset ) do
21382136 { index , metadata_key } ->
2139- Ash.Resource . put_metadata ( result_for_changeset , metadata_key , index )
2137+ Ash.Resource . put_metadata ( result , metadata_key , index )
21402138
21412139 nil ->
21422140 # Compatibility fallback
21432141 Ash.Resource . put_metadata (
2144- result_for_changeset ,
2142+ result ,
21452143 :bulk_create_index ,
21462144 changeset . context [ :bulk_create ] [ :index ]
21472145 )
21482146 end
2149- end
2150- end )
2151- |> Enum . filter ( & & 1 )
2147+ end )
2148+ else
2149+ changesets
2150+ |> Enum . map ( fn changeset ->
2151+ identity =
2152+ changeset . attributes
2153+ |> Map . take ( keys )
2154+
2155+ result_for_changeset = Map . get ( results_by_identity , identity )
2156+
2157+ if result_for_changeset do
2158+ if ! opts [ :upsert? ] do
2159+ maybe_create_tenant! ( resource , result_for_changeset )
2160+ end
2161+
2162+ case get_bulk_operation_metadata ( changeset ) do
2163+ { index , metadata_key } ->
2164+ Ash.Resource . put_metadata ( result_for_changeset , metadata_key , index )
2165+
2166+ nil ->
2167+ # Compatibility fallback
2168+ Ash.Resource . put_metadata (
2169+ result_for_changeset ,
2170+ :bulk_create_index ,
2171+ changeset . context [ :bulk_create ] [ :index ]
2172+ )
2173+ end
2174+ end
2175+ end )
2176+ |> Enum . concat ( results )
2177+ |> Enum . filter ( & & 1 )
2178+ |> Enum . uniq_by ( & Map . take ( & 1 , keys ) )
2179+ end
21522180
21532181 { :ok , results }
21542182 end
@@ -3734,6 +3762,16 @@ defmodule AshPostgres.DataLayer do
37343762 end
37353763 end
37363764
3765+ # checks if any of the attributes in the list of keys are generated and missing from any of the changesets
3766+ # if so, we can't match the created record to the changeset by the identity and just need to zip the return
3767+ # values with the changesets
3768+ defp any_generated_keys_missing? ( keys , resource , changesets ) do
3769+ Enum . any? ( keys , fn key ->
3770+ Ash.Resource.Info . attribute ( resource , key ) . generated? &&
3771+ Enum . any? ( changesets , fn changeset -> is_nil ( changeset . attributes [ key ] ) end )
3772+ end )
3773+ end
3774+
37373775 defp get_bulk_operation_metadata ( changeset ) do
37383776 changeset . context
37393777 |> Enum . find_value ( fn
0 commit comments