I have a model containing Transactions and Splits. The splits are children of transactions. I’m trying to first insert a new transaction, pick-up the freshly generated transaction.uuid, and use that value to insert into the child row to be created in the next step. I’m having trouble finding a way to reference the fresh minted uuid from the first step in the insert on child. What would be considered a good way to handle this? Thanks.
test "SPLIT inserts via Ecto.Multi style transaction." do
multi =
Ecto.Multi.new()
|> Ecto.Multi.insert(:transaction, create_transaction(transaction_map()))
|> Ecto.Multi.insert(:split, create_split(split_map(:transaction)))
case Repo.transaction(multi) do
{:ok, _results} ->
IO.puts("Success")
{:error, :transaction, changeset, _changes} ->
IO.inspect(changeset.errors, label: "Transaction insert failed.")
{:error, :split, changeset, _changes} ->
IO.inspect(changeset.errors, label: "split insert failed.")
end
end
test "SPLIT inserts via Ecto.Multi style transaction." do
multi =
Ecto.Multi.new()
|> Ecto.Multi.insert(:transaction, create_transaction(transaction_map()))
|> Ecto.Multi.insert(:split, fn %{transaction: transaction} ->
# `transaction` is the inserted transaction a step before
create_split(transaction.id)
end)
case Repo.transaction(multi) do
{:ok, _results} ->
IO.puts("Success")
{:error, :transaction, changeset, _changes} ->
IO.inspect(changeset.errors, label: "Transaction insert failed.")
{:error, :split, changeset, _changes} ->
IO.inspect(changeset.errors, label: "split insert failed.")
end
end
Thanks! I had to come to grips with fact that multi.insert expects either struct or changeset (not a map), but once I figured that out, your tip provided the key insight. I forgot to realize that the |> operator was passing the result from the first step in in all along! Thanks for your help!
test "SPLIT inserts via transaction." do
multi =
Ecto.Multi.new()
|> Ecto.Multi.insert(
:transaction,
transaction_changeset()
)
|> Ecto.Multi.insert(:split, fn %{transaction: transaction} ->
# pattern match on result from previous step to pull out the transaction piece.
split_changeset(transaction)
end)
case Repo.transaction(multi) do
{:ok, _results} ->
IO.puts("Success")
{:error, :transaction, changeset, _changes} ->
IO.inspect(changeset.errors, label: "Transaction insert failed.")
{:error, :split, changeset, _changes} ->
IO.inspect(changeset.errors, label: "split insert failed.")
end
end