【问题标题】:Symfony CollectionType update EntitiesSymfony CollectionType 更新实体
【发布时间】:2020-11-10 19:21:47
【问题描述】:

我不敢相信其他人没有遇到这种情况,但我无法找到解决方案。

假设我有两种实体类型,A 和 B 具有一对多的关系。 A 有一个 B 的集合。

A 的表单中 B 的 CollectionType,B 的自定义 entry_typeallow_addallow_delete 设置为 true。创建/填充/呈现表单时,Bs 的字段由它们在集合中的索引标识。表单回传时,字段又根据索引映射回B实体。

如果数据库同时决定以不同的顺序返回 B 怎么办?然后值在 Bs 上交换!我不能这样,因为其他实体会引用 B,现在它们已经改变了它们的含义!

即使数据库没有更改顺序,删除 B 时也会出现同样的问题:字段通过 B 移动并删除了另一个字段! (好吧,我不是 100% 肯定会发生这种情况,因为在发布字段的编号上存在差距。)我发现这个类似的问题在创建另一个时确实发生(Symfony CollectionType regards deletion+creation as a modification of an item),但是那种偏离问题的方法并且没有可用的答案。

如何确保表单正在更新用户实际编辑的实体?

我已经尝试将 Bs 的 ID 呈现为 HiddenType,但随后表单正确地抱怨该 ID 没有设置器。无论如何,它可能会在错误的 B 上强制使用 ID,而 Doctrine 不喜欢这样。我想我可以将 Bs 添加为未映射并手动将值复制到正确的对象,但这会破坏 Symfony 的表单系统的很大一部分。

我之前使用过CollectionType,但不适用于在其他地方引用的实体。然后,我将删除所有以前的实体并从发布的数据中重新创建集合。但我现在不能这样做,可以吗?

【问题讨论】:

  • 如果我关心引用保持一致,我使用 EntityType,它将通过它们的 id 识别条目。如果我关心引用一致性,我不会通过collectiontype编辑相关的entities,我建议不要这样做,而是使用js-“magic”,以单独的形式专门编辑相关实体并通过 ajax 或其他方式仅更新该实体。
  • @Jakumi EntityType 不允许编辑包含的实体,所以这在@msg 你认为是正确的在这里不起作用。 indexBy="id" 通过 B 的 ID 识别表单字段,并在回发时更新正确的对象!它甚至会删除用户从集合中删除的实体(实际上并未删除,而是将 FK 设置为 NULL)。让它成为答案,我会接受!这可能取决于'by_reference' => false 上的CollectionType,尚未检查。
  • @kiw true,EntityType 不允许编辑包含的实体,但您可以通过 ajax 显示单独的表单(这基本上是我提出的,但显然没有很好地转移)来编辑相关的实体分开。 indexBy 可能是一个更强大和用户友好的解决方案。
  • @Jakumi 它确实转移了,我只是没有承认 ;) 我想避免使用 ajax,因为它需要更多的工作,并且还可以避免用户提交大量单独的表单。

标签: symfony doctrine-orm


【解决方案1】:

从学说 2.1 开始,可以更改 how associations are indexed。这将允许您使用 id 作为集合键(因为该字段必须是唯一的):

@OneToMany(targetEntity="B", mappedBy="A", indexBy="id")

您可能还需要启用orphanRemoval,以便实际删除数据,而不是刚刚设置为null 的关系。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 2016-09-15
    • 2018-05-29
    • 1970-01-01
    • 2016-03-12
    • 2018-04-28
    相关资源
    最近更新 更多