在Doctrine ORM中保留两个不同版本的实体

时间:2018-10-09 19:31:46

标签: symfony doctrine-orm doctrine

我正在按照以下要求进行Symfony4 / Doctrine / MySQL项目:

  • 用户只有在获得管理员批准后才能创建在公共前端可见的实体(例如帖子)

  • 当用户在批准/发布后编辑其帖子时,需要再次批准更改的帖子,然后更改才能在前端显示。但是,在等待批准期间,帖子的旧批准版本必须在前端保持可见。

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

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

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

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

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

1 个答案:

答案 0 :(得分:0)

因为我现在正在解决这个问题,所以我想分享一下我的方法。 实体是对某物的请求。每次更改时,更改都应保留。

方法:

  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扩展名。您可以在仓库中实现不同的搜索功能,并通过扩展名(排序,引用...)来处理表示。 我创建了一个API,该API可以同时执行以下操作:返回最新版本并返回所有版本(具有或没有root或最新),但是仅在必要时才在前端使用后者。

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