【问题标题】:Ecto's :on_replace :delete option doesn't work for has_many associationEcto 的 :on_replace :delete 选项不适用于 has_many 关联
【发布时间】:2017-10-15 05:16:20
【问题描述】:

我有一个带有 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 在编辑时从数据库中清除所有以前提交的关联值吗?

【问题讨论】:

    标签: elixir phoenix-framework ecto


    【解决方案1】:

    如果属性 on_replace: 设置为 :delete 以用于模式中的某些关联,则当为此类结构创建变更集时,Ecto 会自动为每个先前保存的关联添加带有操作 :replace 的更改。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-21
      • 1970-01-01
      相关资源
      最近更新 更多