首页 > 解决方案 > 在 Doctrine ORM 中保留实体的两个不同版本

问题描述

我正在开发具有以下要求的 Symfony4/Doctrine/MySQL 项目:

这意味着我必须保留每个“发布”实体的两个版本:前端的批准版本和后端的工作中版本。

在过去有类似要求的项目中,我尝试了不同的方法来解决这个问题:

  1. 使用“版本化行为”(这是在 Symfony1/Propel 时代使用 sfPropelVersionableBehaviorPlugin)。为了在前端显示,如果一个实体未被批准,我必须获取以前的版本,直到找到最新的批准版本。

  2. 使用与主“发布”实体具有相同字段定义的第二个实体/数据库表“ApprovedPost”。当一个帖子被管理员批准后,它将被复制到 ApprovedPost 表中。前端仅在 ApprovedPost 表上运行。

实施这种行为的当前最佳实践是什么?

标签: symfonydoctrine-ormdoctrine

解决方案


因为我现在正在解决这个问题,所以我想分享我的方法。实体是对某事的请求。每次发生变化时,都应该保留这些变化。

该方法:

  1. 在每个编辑操作中,都会创建一个新实体行。
  2. 该实体有一个“已批准”标志和一个 createdAt Date 字段。
  3. 请求具有可为空的一对一自关系(指向根/父实体)。
  4. 自定义存储库用于访问数据库。
  5. 修改了典型的 find 和 findAll 方法:它们搜索已批准的最新版本(通过 createdAt 字段)。
  6. 搜索是通过自定义 SQL/DQL 完成的:(WHERE id = ?1 OR WHERE parent-id = ?1) AND WHERE approved = true SORT BY created_at DESC LIMIT 1

可以添加更多功能,如启用/禁用、删除等...

如果您想呈现页面服务器端并显示更改或旧版本,我建议您编写例如 Twig 扩展。您可以在 repo 中实现不同的搜索功能,并通过扩展处理表示(排序、引用 ...)。我创建了一个 API,它能够同时做到:返回最新版本并返回所有版本(有或没有 root 或最新版本),但我仅在必要时在前端使用后者。

就像 dbrumann 所说,这是一种固执己见的方法(我喜欢自定义存储库,因为我可以创建它们类型安全,并且可以将应用程序与持久性逻辑分离)。


推荐阅读