Ecto multi build_assoc 在列表中
Ecto multi build_assoc on a list
我想在 has_many
的多事务中插入一个列表。像这样的东西:
Ecto.Multi.new()
|> Ecto.Multi.insert(:main, Main.changeset(%Main{}, attrs))
|> Ecto.Multi.insert(:child, fn %{main: main} ->
Ecto.build_assoc(main, :child, %{name: "aaa"}) # inserts just one
end)
|> Ecto.Multi.run(:child, fn _, %{main: main} ->
Enum.map(attrs.children, &create_child/1) # doesn't return a multi and doesn't build the assoc
end)
|> Repo.transaction()
正如我所评论的那样,我没有找到可行的解决方案。
|> Ecto.Multi.insert(:child, fn %{main: main} ->
Ecto.build_assoc(main, :child, %{name: "aaa"})
end)
这只插入一行,我有一个列表要插入。
|> Ecto.Multi.run(:child, fn _, %{main: main} ->
Enum.map(attrs.children, &create_child/1)
end)
这不是 return multi,也不会与 main
建立关联。
我也找到了这个表格,但它也适用于单个插入:
|> Multi.run(:user, fn %{organisation: organisation} ->
User.changeset(User, user_params)
|> Ecto.Changeset.put_assoc(organisation)
|> Repo.insert # returns a {:ok, user} or {:error, changeset}
end)
Ecto.Multi
不是在插入多条记录之后命名的,而是在单个事务中分组多个操作之后命名的。
有Ecto.Multi.insert_all/5
, but it has the same limitations as Repo.insert_all/3
,即无法插入到多个表中。 (此外,它不支持自动时间戳,还有其他一些限制。)
只需使用正常的迭代 Enum.each/2
或类似的方法,根据需要生成尽可能多的插入语句,并将它们全部包装到一个事务中。
要将多个 children 收集到 Ecto.Multi
中,可以使用 Enum.reduce
和 Ecto.Multi
作为累加器:
multi =
Ecto.Multi.new()
|> Ecto.Multi.insert(:main, Main.changeset(%Main{}, attrs))
attrs.children
|> Enum.reduce(
multi,
&Ecto.Multi.insert(&2, :child, create_child(&1))
)
|> Repo.transaction()
我想在 has_many
的多事务中插入一个列表。像这样的东西:
Ecto.Multi.new()
|> Ecto.Multi.insert(:main, Main.changeset(%Main{}, attrs))
|> Ecto.Multi.insert(:child, fn %{main: main} ->
Ecto.build_assoc(main, :child, %{name: "aaa"}) # inserts just one
end)
|> Ecto.Multi.run(:child, fn _, %{main: main} ->
Enum.map(attrs.children, &create_child/1) # doesn't return a multi and doesn't build the assoc
end)
|> Repo.transaction()
正如我所评论的那样,我没有找到可行的解决方案。
|> Ecto.Multi.insert(:child, fn %{main: main} ->
Ecto.build_assoc(main, :child, %{name: "aaa"})
end)
这只插入一行,我有一个列表要插入。
|> Ecto.Multi.run(:child, fn _, %{main: main} ->
Enum.map(attrs.children, &create_child/1)
end)
这不是 return multi,也不会与 main
建立关联。
我也找到了这个表格,但它也适用于单个插入:
|> Multi.run(:user, fn %{organisation: organisation} ->
User.changeset(User, user_params)
|> Ecto.Changeset.put_assoc(organisation)
|> Repo.insert # returns a {:ok, user} or {:error, changeset}
end)
Ecto.Multi
不是在插入多条记录之后命名的,而是在单个事务中分组多个操作之后命名的。
有Ecto.Multi.insert_all/5
, but it has the same limitations as Repo.insert_all/3
,即无法插入到多个表中。 (此外,它不支持自动时间戳,还有其他一些限制。)
只需使用正常的迭代 Enum.each/2
或类似的方法,根据需要生成尽可能多的插入语句,并将它们全部包装到一个事务中。
要将多个 children 收集到 Ecto.Multi
中,可以使用 Enum.reduce
和 Ecto.Multi
作为累加器:
multi =
Ecto.Multi.new()
|> Ecto.Multi.insert(:main, Main.changeset(%Main{}, attrs))
attrs.children
|> Enum.reduce(
multi,
&Ecto.Multi.insert(&2, :child, create_child(&1))
)
|> Repo.transaction()