【发布时间】:2020-11-10 19:21:47
【问题描述】:
我不敢相信其他人没有遇到这种情况,但我无法找到解决方案。
假设我有两种实体类型,A 和 B 具有一对多的关系。 A 有一个 B 的集合。
A 的表单中 B 的 CollectionType,B 的自定义 entry_type,allow_add 和 allow_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