我有主要数据和详细数据。我想一次插入两个。
-------
main
-------
id
name
-------
---------
detail
---------
id
main_id
name
---------我正在使用ecto的多事务。然而,我不知道如何立即插入。
main = [name: "zaku"]
details = [%{main_id: 1, name: "hoge"}, %{main_id: 1, name: "moja"},]
Multi.new()
|> Multi.insert(:main, Main.changeset(%Main{}, main))
|> Multi.insert(:detail, Detail.changeset(%Detail{}, details))
|> Repo.transaction()详细信息插入中的零件不起作用。我能为它做些什么?
发布于 2020-04-23 17:25:21
由于事务,子项的插入不起作用。尝试插入Detail时,父对象尚不存在。
通常使用Ecto.build_assoc/3插入从属记录,或者不推荐使用!您可以摆脱事务,使用两个查询逐个插入它们-这是可行的。
发布于 2020-04-24 05:01:24
我认为您的示例类似于the solution for your other example,您只需要通过调用transaction/1函数来结束多个查询:
alias Ecto.Multi
alias Ecto.Repo
user = get_user_params_from_form() # <-- or where-ever you are getting data
email = get_email_params_from_form()
Multi.new()
|> Multi.insert(:user, User.changeset(%User{}, user))
|> Multi.insert(
:email,
# Capture the id from the previous operation
fn %{
user: %User{
id: user_id
}
} ->
Email.changeset(%Email{user_id: user_id}, email)
end
)
|> Repo.transaction()就我个人而言,我觉得Multi的东西不太容易使用,所以有时我更喜欢另一种语法,在这种语法中,您可以将函数传递给Repo.transaction/2 callback。粗略地说,这看起来像这样:
Repo.transaction(fn ->
with {:ok, thing1} <- create_thing1(attrs1) do
create_thing2(attrs2)
else
{:error, e} -> Repo.rollback(e)
end
end)
def create_thing1(attrs \\ %{}) do
%ThingOne{}
|> ThingOne.changeset(attrs)
|> Repo.insert()
end
def create_thing2(attrs \\ %{}) do
%ThingTwo{}
|> ThingTwo.changeset(attrs)
|> Repo.insert()
end应该指出的是,此模式可用于包装事务中的任何任务。例如,如果"thing2“要与第三方应用程序接口交互。
https://stackoverflow.com/questions/61383569
复制相似问题