我有一个具有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
>
]
...
我的第一条记录被覆盖。
答案 0 :(得分:1)
这是Power BI / add refresh button on report view的预期行为,因为它打算与完整数据集一起使用。实际上,您的问题在Ecto文档中得到了很好的描述:put_assoc\4
可以提供地图或关键字列表以将相关数据更新为 只要它们具有匹配的主键。例如, put_assoc(changeset,:comments,[%{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/4
和has_many
。