Используйте Ecto.Multi для обновления таблицы дважды в одной транзакции - PullRequest
0 голосов
/ 16 октября 2018

Рассмотрим сценарий, в котором вы пытаетесь смоделировать регистрацию банковской транзакции.Транзакция имеет сумму, тип (кредит или дебет) и связана с учетной записью.

В случае добавления новой банковской транзакции я могу это сделать, и она хорошо работает:

Multi.new()
|> Multi.insert(:transaction, transaction_changeset)
|> Multi.update(:account, account_changeset)
|> Repo.transaction()

Обновление существующей банковской транзакции немного сложнее.Это потому, что пользователь может изменить не только сумму, но и аккаунт.Обновление существующей транзакции может означать удаление суммы из предыдущей учетной записи, в дополнение к добавлению суммы к текущей учетной записи.Я пробовал это, но я не уверен, как выразить то, что я пытаюсь сделать, используя Ecto.Multi.

Multi.new()
|> Multi.update(:transaction, transaction_changeset)
|> Multi.update(:account, previous_account_changeset)
|> Multi.update(:account, current_account_changeset)
|> Repo.transaction()

Ошибка времени выполнения: учетная запись уже является членом Ecto.Multi:

1 Ответ

0 голосов
/ 16 октября 2018

Проблема здесь в том, что вы дважды используете клавишу :account. Из документации :

Ecto.Multi позволяетПакетные операции, которые должны выполняться в одной транзакции с базой данных, позволяют анализировать операции в очереди, фактически не выполняя их.Каждой операции присваивается уникальное имя, которое идентифицирует ее результат в случае успеха или неудачи.


Вы можете выбрать любое понравившееся имя, если оно уникальное. Просто измените вашу транзакцию на что-то вроде:

Multi.new
|> Multi.update(:transaction, transaction_changeset)
|> Multi.update(:previous_account, previous_account_changeset)
|> Multi.update(:current_account, current_account_changeset)
|> Repo.transaction
...