【问题标题】:Update Ecto Changeset Assocations更新 Ecto 变更集关联
【发布时间】:2021-09-29 22:23:30
【问题描述】:

我有一个具有has_many 关联的 Ecto 架构设置。我希望能够动态添加/删除关联,保持初始关联。

我尝试使用Ecto.Changeset.put_assoc/4,它在加载初始关联时有效,但是每个后续调用都会覆盖初始关联。

change_one = Changeset.put_assoc(changeset, :foo_assocs, [%{index: 1}])
...
foo_assocs: [
  #Ecto.Changeset<
    action: :insert,
    changes: %{index: 1},
    errors: [],
    data: #Linker.CustomForms.FooAssoc<>,
    valid?: true
  >
]
...

如果我再次调用它并添加另一个关联记录:

change_two = Changeset.put_assoc(changeset_one, :foo_assocs, [%{index: 2}])
...
foo_assocs: [
  #Ecto.Changeset<
    action: :insert,
    changes: %{index: 2},
    errors: [],
    data: #Linker.CustomForms.FooAssoc<>,
    valid?: true
  >
]
...

我的第一条记录被覆盖了。

【问题讨论】:

    标签: elixir phoenix-framework ecto


    【解决方案1】:

    这是put_assoc/4 的预期行为,因为它旨在处理完整的数据集。实际上,您的问题在 Ecto 文档中得到了很好的描述:https://hexdocs.pm/ecto/Ecto.Changeset.html#put_assoc/4-example-adding-a-comment-to-a-post

    可以给出地图或关键字列表来更新相关数据 只要他们有匹配的主键。例如, put_assoc(changeset, :cmets, [%{id: 1, title: "changed"}]) 将 找到 :id 为 1 的评论并更新其标题。如果没有评论 有了这样的 id 存在,就会动态创建一个。由于只有一个 给出了评论,任何其他相关评论都将被替换。

    因此,您可以将现有数据与新数据合并并使用put_assoc/4,或者您可以处理您的单一关联,如以下示例,您从孩子那里设置关联

    changeset = %__MODULE__{} |> has_many(:foo_assoc, [%{index: 1}])
    
    %FooChild{index: 2}
    |> Ecto.Changeset.change()
    |> Ecto.Changeset.put_assoc(:parent, changeset)
    |> Repo.insert!()
    

    但我建议阅读上面的链接,了解如何使用put_assoc/4has_many 的更详细说明。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多