请考虑一个您试图对银行交易记录建模的方案。交易具有金额,类型(贷记或借记),并且与帐户相关联。
如果要添加新的银行交易,我可以这样做,并且效果很好:
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的成员:
答案 0 :(得分:3)
此处的问题是您两次使用了:account
键。来自documentation:
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