...
/Run Transactions and Capturing Errors with Ecto.Multi
Run Transactions and Capturing Errors with Ecto.Multi
Learn how to run transactions with Ecto.Multi and examine errors.
The Ecto.Multi struct
The other way to use Repo.transaction is to pass in an Ecto.Multi struct rather than a function. The Ecto.Multi struct allows us to group our database operations into a data structure. When handed to the transaction function, the Multi’s operations run in order. If any of them fail, all of the others are rolled back.
Let’s take a look at an earlier example where we ran a transaction with an anonymous function.
artist = %Artist{name: "Johnny Hodges"}Repo.transaction(fn ->Repo.insert!(artist)Repo.insert!(Log.changeset_for_insert(artist))end)
Here’s how we can rewrite it using Multi.
alias Ecto.Multiartist = %Artist{name: "Johnny Hodges"}multi =Multi.new\|> Multi.insert(:artist, artist)\|> Multi.insert(:log,Log.changeset_for_insert(artist))Repo.transaction(multi)
There’s a lot here, so let’s walk through it.
A walkthrough
-
We created a new
Multiwith thenewfunction. The Ecto team recommends using this approach rather than trying to create the struct directly—don’t try to write something likemulti = %Multi{}. The exact structure ofEcto.Multiis subject to future change. When we callnew, it ensures that the struct will be properly initialized to us. If we create the struct directly, we’re on our own. -
We then add the two insert operations by piping the
Multiinto theinsertfunction. TheEcto.Multimodule has several functions that mirror ...