Elixir 成功更新Repo.update后,异位重新加载属于关联
通过params中的Elixir 成功更新Repo.update后,异位重新加载属于关联,elixir,phoenix-framework,ecto,Elixir,Phoenix Framework,Ecto,通过params中的parent\u id将给定的child的关联从parent\u a更改为parent\u b,会留下一条过时的记录。parent对象 e、 g.(假设参数匹配%{child:%{id:'1',parent_id:'6'}) 更新后检索新关联的父记录的正确方法是什么?目前在EXTO中没有内置的方法。您还存在无法使用预加载的问题,因为关联已预加载 一个选择是: %{child | parent: Repo.get!(Parent, child.parent_id)} 您还可以
parent\u id
将给定的child
的关联从parent\u a
更改为parent\u b
,会留下一条过时的记录。parent
对象
e、 g.(假设参数匹配%{child:%{id:'1',parent_id:'6'}
)
更新后检索新关联的父记录的正确方法是什么?目前在EXTO中没有内置的方法。您还存在无法使用预加载的问题,因为关联已预加载 一个选择是:
%{child | parent: Repo.get!(Parent, child.parent_id)}
您还可以选择在调用
Repo.update
之前不调用预加载,这将阻止关联已加载。强制预加载。默认情况下,Ecto不会预加载已加载的关联
child
|> Child.changeset(params)
|> Repo.update!()
|> Repo.preload(:parent, force: true)
如果您想以不同的方式处理错误,也可以不使用bang更新
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
带有{:ok,child}#句柄错误
结束
defp get_child(child_id)do
案例回购get(儿童,儿童id)do
nil->{:错误,:未找到}
child->{:好的,child}
结束
结束
defp update_child(child,params)do
更新的\u子项=
小孩
|>子变更集(参数)
|>Repo.update!()
|>回购预加载(:父项,强制:真)
营救
exto.InvalidChangesetError中出错->{:error,error.changeset}
运行时错误->{:错误,错误。消息}
结束
使用Ecto 2.0,您现在可以将force:true
传递到Repo.preload
以强制重新加载已加载的关联。来源:@JonathanPerret值得把你的评论变成答案吗?在现代版本的EXTO中,这似乎是解决问题的惯用方法。
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