Ecto:on_replace:delete选项不适用于has_many关联

时间:2017-10-15 05:16:21

标签: elixir phoenix-framework ecto

我有has_many关联的架构:on_replace选项设置为:delete。我有一个带有一组复选框的表单,用于提交新值以作为父实体的关联。我希望在编辑时删除所有先前设置的关联,但是我将新的关联插入到数据库中,旧的仍然保留在数据库中。

提交后的变更集只有新的关联,其中没有id的变化,如下所示:

%{materials: [#Ecto.Changeset<action: :insert,
    changes: %{material: "Cast iron"}, errors: [],
    data: #HrPro.Entities.Material<>, valid?: true>,
    #Ecto.Changeset<action: :insert,
    changes: %{material: "Steel"}, errors: [],
    data: #HrPro.Entities.Material<>, valid?: true>]}

正如您所看到的那样,变更集中没有:id字段,因此我预计以前保存的资料将从数据库中删除,但事实并非如此。

架构如下所示:

schema "entities" do
  has_many :materials, Material, on_replace: :delete
end

def changeset(%Entity{} = entity, attrs \\ %{}) do
  entity
  |> cast(attrs, @allowed_fields)
  |> cast_assoc(:materials)
end

我的安装是:

phoenix 1.3
ecto 2.2.6

我们可以让Ecto在编辑时从数据库中清除所有以前提交的相关值吗?

1 个答案:

答案 0 :(得分:0)

如果属性on_replace:设置为:delete for schema中的某些关联,当为此类结构创建更改集时,Ecto会自动添加更改操作:替换以前保存的每个关联。

在我的情况下问题是我使用了ecto的新的 action :: ignore 功能,不允许Ecto使用空值污染我的数据库(如果在表单中未选中相应的复选框) 。 此功能只是从变更集中删除空关联的所有更改,包括具有操作的那些::替换Ecto从数据库中删除它们所需的更改。

当我停止忽略空值时,一切正常。