gpt4 book ai didi

elixir - Repo.update成功后,Ecto重新加载belongs_to关联

转载 作者:行者123 更新时间:2023-12-02 06:12:22 25 4
gpt4 key购买 nike

通过参数中的 parent_id 将给定 child 的关联从 parent_a 更改为 parent_b 会留下陈旧的record.parent对象。

例如(假设参数匹配 %{child: %{id: '1',parent_id: '6'}})

# ...
child = Repo.get(Child, child_id)
|> preload([:parent])
changeset = Child.changeset(child, child_params)

case Repo.update(changeset) do
{:ok, child} ->
IO.puts child.parent_id # returns '6', or the new, changed `id`
IO.puts child.parent.id # returns '5', or the old id
# child.parent is stale
# ...

更新后检索新关联的父记录的正确方法是什么?

最佳答案

强制预载。默认情况下,Ecto 不会预加载已加载的关联。

child
|> Child.changeset(params)
|> Repo.update!()
|> Repo.preload(:parent, force: true)

或者如果您想以不同的方式处理错误,则无需进行重大更新

child
|> Child.changeset(params)
|> Repo.update()
|> case do
{:ok, child} -> {:ok, Repo.preload(child, :parent, force: true)}
error -> error
end

在一个更现实的错误处理示例中,它可能看起来像这样

with {:ok, child} <- get_child(child_id),
{:ok, child} <- update_child(child, params) do
# Do stuff
else
{:error, %Ecto.Changeset{} = changeset} -> # Handle error
{:error, reason} -> # Handle error
end

defp get_child(child_id) do
case Repo.get(Child, child_id) do
nil -> {:error, :not_found}
child -> {:ok, child}
end
end

defp update_child(child, params) do
updated_child =
child
|> Child.changeset(params)
|> Repo.update!()
|> Repo.preload(:parent, force: true)
rescue
error in Ecto.InvalidChangesetError -> {:error, error.changeset}
error in RuntimeError -> {:error, error.message}
end

关于elixir - Repo.update成功后,Ecto重新加载belongs_to关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34945536/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com