我有一个架构exchange_accounts
和user_profile
user_profile
有一个来自exchange_accounts_id
模式的Foreign_key列exchange_accounts
。我想在需要将user_profile
与exchange_accounts_id
表的主键列关联的exchange_accounts
表中插入数据。
我有create_user_profile
功能
我尝试使用Ecto.Multi.run
现在基本上我不了解两者之间的建立联系。
def create_user_profile(profile_info, dealer_id) do
Ecto.Multi.new()
|> Ecto.Multi.run(:exchange, fn %{exchange: exchange} -> Ecto.build_assoc(exchange, :user_profile)
|> Ecto.Multi.insert(:user, UserProfile.changeset(%UserProfile{}, profile_info))
|> Ecto.Multi.merge(fn %{user: user} ->
bank_detail =
Ecto.build_assoc(user, :bank_details)
|> BankDetails.changeset(profile_info)
Ecto.Multi.new()
|> Ecto.Multi.insert(:bank_detail, bank_detail)
end)
我想在将数据插入user_profile
表中之前执行此操作
而且我尝试使用Ecto.Multi.run
来执行此操作,但是它不起作用。
结果应该是应该在两个表之间建立关联,并且应该插入数据。
whenevr iam试图运行它只是不起作用。我不明白我在哪里错了,使用Ecto.Multi.run
是否正确。
答案 0 :(得分:1)
Ecto.Multi.run/3/5
本身不会执行任何操作,您仍然需要在传递的fn/2
内部执行任何操作。对于您认为成功的操作,此函数需要返回{:ok, val}
,或者如果您认为操作失败,则返回{:error, val}
,以便Ecto知道是否应回滚整个事务。
来自> Ecto 3(如果我没记错的话),Multi insert
,update
等也可以接受fn/1
,其中参数将是multi操作的Map到目前为止。
因此,您可能应该更改此设置:
|> Ecto.Multi.run(:exchange, fn %{exchange: exchange} -> Ecto.build_assoc(exchange, :user_profile)
收件人:
|> Ecto.Multi.insert(:exchange, fn(_) -> Ecto.build_assoc(exchange, :user_profile) end)
或继续运行,但请执行以下操作:
Ecto.build_assoc(exchange, :user_profile)
|> Repo.insert()
然后在用户插入时,使用:exchange
值将其放置在您的user_profile中。
|> Ecto.Multi.insert(:user, fn(%{exchange: exchange}) ->
# now you have access to the `exchange` operation result from the previous step
UserProfile.changeset(%UserProfile{}, profile_info)
end)
您还可以通过在传递给Repo.transaction/1
的闭包内进行常规Repo.insert
等操作,在fn
内将所有这些作为常规代码运行。
Multi允许您显式分离每个操作,并在每个后续步骤中访问每个操作,如果认为事务成功(即使与DB操作无关),则可以做其他可能会或可能不会更改的事情,然后成功返回或以及失败的操作等,以及传递Multi结构以通过Multi.merge
添加其他内容。