diff --git a/lib/data_layer.ex b/lib/data_layer.ex index 3bad7f45..b984c4db 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -2124,34 +2124,57 @@ defmodule AshPostgres.DataLayer do end) results = - changesets - |> Enum.map(fn changeset -> - identity = - changeset.attributes - |> Map.take(keys) + if opts[:upsert?] do + changesets + |> Enum.map(fn changeset -> + identity = + changeset.attributes + |> Map.take(keys) - result_for_changeset = Map.get(results_by_identity, identity) + result_for_changeset = Map.get(results_by_identity, identity) - if result_for_changeset do + if result_for_changeset do + if !opts[:upsert?] do + maybe_create_tenant!(resource, result_for_changeset) + end + + case get_bulk_operation_metadata(changeset) do + {index, metadata_key} -> + Ash.Resource.put_metadata(result_for_changeset, metadata_key, index) + + nil -> + # Compatibility fallback + Ash.Resource.put_metadata( + result_for_changeset, + :bulk_create_index, + changeset.context[:bulk_create][:index] + ) + end + end + end) + |> Enum.filter(& &1) + else + results + |> Enum.zip(changesets) + |> Enum.map(fn {result, changeset} -> if !opts[:upsert?] do - maybe_create_tenant!(resource, result_for_changeset) + maybe_create_tenant!(resource, result) end case get_bulk_operation_metadata(changeset) do {index, metadata_key} -> - Ash.Resource.put_metadata(result_for_changeset, metadata_key, index) + Ash.Resource.put_metadata(result, metadata_key, index) nil -> # Compatibility fallback Ash.Resource.put_metadata( - result_for_changeset, + result, :bulk_create_index, changeset.context[:bulk_create][:index] ) end - end - end) - |> Enum.filter(& &1) + end) + end {:ok, results} end diff --git a/test/bulk_create_test.exs b/test/bulk_create_test.exs index 296742fd..c18d8d1a 100644 --- a/test/bulk_create_test.exs +++ b/test/bulk_create_test.exs @@ -4,7 +4,7 @@ defmodule AshPostgres.BulkCreateTest do use AshPostgres.RepoCase, async: false - alias AshPostgres.Test.{Post, Record} + alias AshPostgres.Test.{IntegerPost, Post, Record} require Ash.Query import Ash.Expr @@ -356,6 +356,18 @@ defmodule AshPostgres.BulkCreateTest do |> Ash.Query.load(:ratings) |> Ash.read!() end + + test "bulk creates with integer primary key return records" do + %Ash.BulkResult{records: records} = + Ash.bulk_create!( + [%{title: "first"}, %{title: "second"}, %{title: "third"}], + IntegerPost, + :create, + return_records?: true + ) + + assert length(records) == 3 + end end describe "validation errors" do