如何在Laravel中实现模型修订?

时间:2013-08-29 05:08:53

标签: php mysql laravel eloquent revisionable

这个问题适用于我用PHP编写的pastebin应用程序。

我做了一些研究,虽然我找不到符合我需求的解决方案。我有一个这种结构的表:

+-----------+------------------+------+-----+---------+----------------+
| Field     | Type             | Null | Key | Default | Extra          |
+-----------+------------------+------+-----+---------+----------------+
| id        | int(12) unsigned | NO   | PRI | NULL    | auto_increment |
| author    | varchar(50)      | YES  |     |         |                |
| authorid  | int(12) unsigned | YES  |     | NULL    |                |
| project   | varchar(50)      | YES  |     |         |                |
| timestamp | int(11) unsigned | NO   |     | NULL    |                |
| expire    | int(11) unsigned | NO   |     | NULL    |                |
| title     | varchar(25)      | YES  |     |         |                |
| data      | longtext         | NO   |     | NULL    |                |
| language  | varchar(50)      | NO   |     | php     |                |
| password  | varchar(60)      | NO   |     | NULL    |                |
| salt      | varchar(5)       | NO   |     | NULL    |                |
| private   | tinyint(1)       | NO   |     | 0       |                |
| hash      | varchar(12)      | NO   |     | NULL    |                |
| ip        | varchar(50)      | NO   |     | NULL    |                |
| urlkey    | varchar(8)       | YES  | MUL |         |                |
| hits      | int(11)          | NO   |     | 0       |                |
+-----------+------------------+------+-----+---------+----------------+

这适用于pastebin应用程序。我基本上想要粘贴修改,这样如果你打开粘贴#1234,它会显示该粘贴的所有过去版本。

我想到了三种方式:

方法1

有一个带有id和old_id或其他东西的修订表,对于每个ID,我会插入所有旧版本,所以如果我的结构看起来像这样:

rev3: 1234
rev2: 1233
rev1: 1232

该表格将包含以下数据:

+-------+----------+
| id    | old_id   |
+-------+----------+
| 1234  | 1233     |
| 1234  | 1232     |
| 1233  | 1232     |
+-------+----------+

我遇到的问题是它引入了大量重复数据。修正得到的越多,它不仅有更多的数据,而且我需要为修订表中的每个新粘贴执行N次插入,这对于大N来说并不是很好。

方法2

我可以将child_id添加到顶部的粘贴表中,然后更新它。然后,在获取粘贴时,我将继续查询每个child_id及其child_id的数据库等等......但问题是,每次打开包含许多修订的粘贴时,都会引入太多数据库读取。

方法3

还涉及单独的修订表,但对于与方法1相同的方案,它将存储如下数据:

+-------+-----------------+
| id    | old_id          |
+-------+-----------------+
| 1234  | 1233,1232       |
| 1233  | 1232            |
+-------+-----------------+

当有人打开粘贴1234时,我将使用IN子句来获取那里的所有子粘贴数据。

哪种方法最好?还是有更好的方法?我正在使用具有Eloquent ORM的Laravel 4框架。

编辑:我可以使用oneToMany关系执行方法1吗?我知道我可以使用Eager Loading来获取所有修订,但是如何插入它们而不必进行肮脏的黑客攻击?

编辑:我想出了如何处理上述问题。我将添加一个答案来结束这个问题。

3 个答案:

答案 0 :(得分:8)

如果您使用的是Laravel 4,请尝试Revisionable。这可能满足您的需求

答案 1 :(得分:2)

所以这就是我在做的事情:

说这是修订流程:

1232 -> 1233 -> 1234
1232 -> 1235

所以这是我的修订表的样子:

+----+--------+--------+
| id | new_id | old_id |
+----+--------+--------+
| 1  | 1233   | 1232   |
| 2  | 1234   | 1233   |
| 3  | 1234   | 1232   |
| 4  | 1235   | 1232   |
+----+--------+--------+

ID 2和3显示当我打开1234时,它应该在列表中显示1233和1232作为修订。

现在执行位:我将使用Paste模型与Revision模型有一对多的关系。

  • 当我为现有粘贴创建新修订时,我将运行批量插入,不仅添加当前的new_id和old_id对,而且将当前new_id与所有与old_id相关联的修订配对。
  • 当我打开一个粘贴时 - 我将通过查询new_id来做,我将基本上获得修订表中的所有关联行(使用定义hasMany的粘贴模型中的函数('Revision','new_id'))和将显示给用户。

我也在考虑在“查看粘贴”页面的“修订历史记录”部分中显示每个修订的作者,所以我想我还会在修订表中添加一个作者列,这样我就不会需要返回并查询主粘贴表以获取作者。

所以就是这样!

答案 2 :(得分:1)

有一些很棒的软件包可以帮助您保持模型修订:

  • 如果您只想保留模型修订版,可以使用:

Revisionable

  • 如果您还想随时使用自定义数据记录任何其他操作,则可以使用:

Laravel Activity Logger

尊敬的提及: