symfony - 在 Doctrine ORM 中保留实体的两个不同版本
问题描述
我正在开发具有以下要求的 Symfony4/Doctrine/MySQL 项目:
用户只能在管理员批准后创建在公共前端可见的实体(例如帖子)
当用户在批准/发布后编辑他的帖子时,需要再次批准更改的帖子,然后更改才会在前端可见。但是,在等待批准时,帖子的旧批准版本必须在前端保持可见。
这意味着我必须保留每个“发布”实体的两个版本:前端的批准版本和后端的工作中版本。
在过去有类似要求的项目中,我尝试了不同的方法来解决这个问题:
使用“版本化行为”(这是在 Symfony1/Propel 时代使用 sfPropelVersionableBehaviorPlugin)。为了在前端显示,如果一个实体未被批准,我必须获取以前的版本,直到找到最新的批准版本。
使用与主“发布”实体具有相同字段定义的第二个实体/数据库表“ApprovedPost”。当一个帖子被管理员批准后,它将被复制到 ApprovedPost 表中。前端仅在 ApprovedPost 表上运行。
实施这种行为的当前最佳实践是什么?
解决方案
因为我现在正在解决这个问题,所以我想分享我的方法。实体是对某事的请求。每次发生变化时,都应该保留这些变化。
该方法:
- 在每个编辑操作中,都会创建一个新实体行。
- 该实体有一个“已批准”标志和一个 createdAt Date 字段。
- 请求具有可为空的一对一自关系(指向根/父实体)。
- 自定义存储库用于访问数据库。
- 修改了典型的 find 和 findAll 方法:它们搜索已批准的最新版本(通过 createdAt 字段)。
- 搜索是通过自定义 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 所说,这是一种固执己见的方法(我喜欢自定义存储库,因为我可以创建它们类型安全,并且可以将应用程序与持久性逻辑分离)。
推荐阅读
- html - Bootstrap 折叠菜单在打开时不应占据整个屏幕宽度
- php - php mysql如何获取数组中的值
- c# - 运行c#时如何隐藏浏览器硒?
- python - 如何进行从 JSON 格式到表格格式的特征映射(pop)?
- python - 不使用 urllib.request 处理互联网
- ibm-doors - 替换dxl中两个模块之间的字符串
- javascript - AngluarJS 和 FileReader 如何将文件保存到路径
- python - 删除字符串池
- android - Gradle 插件版本与领域 gradle 版本 Android Studio 冲突
- html - 离子选择不从 ng-model 中选择多个值