Ecto.Changeset 更新时出现相关模型错误

Ecto.Changeset related model error on update

Ecto 在更新 has_one 关联时给我一个错误:

有问题的模型:

defmodule Something.Parent do
  has_one :thing, Something.thing

  @required_fields ~w(field1 field2 thing)
end

控制器更新动作

def update(conn, %{"id" => id, "parent" => parent_params}) do                            
   parent = Repo.get!(Parent, id) |> Repo.preload(:thing)

   changeset = Parent.changeset(parent, parent_params)                                                        

   case Repo.update(changeset) do
     {:ok, _parent} ->                                                                            
       conn                                                                                     
       |> put_flash(:info, "Parent updated successfully")                                         
       |> redirect(to: parent_path(conn, :index))                                                                             
     {:error, changeset} ->
       render(conn, "edit.html", parent: parent, changeset: changeset) 
   end                                                               
 end

参数

parent = %{"some_number" => "902", "thing" => %{"somethingfield" => "blah", "parent_id" => " 8"}

错误

you are attempting to change relation :thing of
Whatever.Parent, but there is missing data.

By default, if the parent model contains N children, at least the same
N children must be given on update. In other words, it is not possible
to orphan embed nor associated records, attempting to do so results
in this error message.

It is possible to change this behaviour by setting :on_replace when
defining the relation. See `Ecto.Changeset`'s section on related models
for more info.

根据文档,父模型上的变更集功能似乎看到 'Thing' 从父模型中孤立 - 但我不明白为什么?

new/create 操作工作得很好。

这里的问题是您有一个 thing 关联到您要更改的父对象。

如错误消息所述,您可以使用 has_one/3

on_replace 选项更改此设置

:on_replace - The action taken on associations when the model is replaced when casting or manipulating parent changeset. May be :raise (default), :mark_as_invalid, :nilify, or :delete. See Ecto.Changeset‘s section on related models for more info.

Ecto.Changeset docs.

这是 Ecto 中的一个错误。通过此提交修复了 master。

https://github.com/elixir-lang/ecto/commit/6c1c04304ebecf5ccae4a49008deab814e034d2b