Вы должны использовать Repo.rollback при сбоях.В документах написано The transaction will return the value given as {:error, value}
, так что это можно сделать с помощью сопоставления с образцом, как вы упомянули:
def create_account(company_name, ...) do
Repo.transaction(fn ->
account = case Account.create_account(%{ # ... attributes here }) do
{:ok, account} -> account
{:error, changeset} -> Repo.rollback(changeset)
end
# insert other model
{:ok, account}
end)
end
Таким образом, ваша функция вернет {:ok, account}
при успехе и {:error, changeset}
при любом сбое, с которым она столкнется.Поскольку вы вставляете несколько вещей, возможно, вы захотите их различить, например, так:
account = case Account.create_account(%{ # ... attributes here }) do
{:ok, account} -> account
{:error, changeset} -> Repo.rollback({:account, changeset})
end
case User.create_user(account, %{ # ... attributes here }) do
{:ok, user} -> :ok
{:error, changeset} -> Repo.rollback({:user, changeset})
end
В этом случае функция вернет {:ok, account}
, если все пойдет хорошо, {:error, {:account, account_changeset}}
, если вставка учетной записи не удаласьи {:error, {:user, user_changeset}}
в случае сбоя вставки пользователем.