Ecto 的 :on_replace :delete 选项不适用于 has_many 关联
Ecto's :on_replace :delete option doesn't work for has_many association
我有 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 在编辑时从数据库中清除所有先前提交的关联值?
看来,如果 属性 on_replace: 设置为 :delete 对于架构中的某些关联,当为此类结构创建变更集时,Ecto 会自动添加更改操作:替换为每个以前保存的关联。
在我的例子中,问题是我使用了 ecto 的新 action: :ignore 功能来不允许 Ecto 用空值污染我的数据库(如果相应的复选框是在表格中未选中)。
并且此功能只是从变更集中删除空关联的所有更改,包括那些带有操作的更改::替换,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 在编辑时从数据库中清除所有先前提交的关联值?
看来,如果 属性 on_replace: 设置为 :delete 对于架构中的某些关联,当为此类结构创建变更集时,Ecto 会自动添加更改操作:替换为每个以前保存的关联。
在我的例子中,问题是我使用了 ecto 的新 action: :ignore 功能来不允许 Ecto 用空值污染我的数据库(如果相应的复选框是在表格中未选中)。 并且此功能只是从变更集中删除空关联的所有更改,包括那些带有操作的更改::替换,Ecto 需要将它们从数据库中删除。
当我停止忽略空值时,一切正常。