vildanbina/laravel-revisions

创建任何 Eloquent 模型记录及其底层关系的多个修订版本

dev-master 2021-09-28 07:17 UTC

This package is not auto-updated.

Last update: 2024-09-25 20:22:58 UTC


README

为任何 Eloquent 模型及其关系创建修订版本

Build Status StyleCI Scrutinizer Code Quality

概览

本包允许您为任何 Eloquent 模型记录及其底层关系创建修订版本。

  • 创建修订版本后,它将存储在 revisions 数据库表中。
  • 在模型更新时,将自动使用 updated Eloquent 事件创建修订版本
  • 您还可以使用 saveAsRevision() 手动创建修订版本
  • 当记录被强制删除时,其所有修订版本也将自动删除,使用 deleted Eloquent 事件

如前所述,此包可以与模型记录一起修订整个关系。

酷的是,它还可以从头开始重新创建关系记录,如果它们在模型记录的生命周期中途中被强制删除。

可以修订的关系类型:hasOnemorphOnehasManymorphManybelongsToManymorphToMany

安装

通过 Composer 安装包(适用于 Laravel 6.0 及以上版本

composer require vildanbina/laravel-revisions

通过 Composer 安装包(适用于 Laravel 5.8

composer require vildanbina/laravel-revisions:3.1.0

通过 Composer 安装包(适用于 Laravel 5.7 及以下版本

composer require vildanbina/laravel-revisions:2.0.0

使用以下命令发布配置文件

php artisan vendor:publish --provider="vildanbina\Revisions\ServiceProvider" --tag="config"

使用以下命令发布迁移文件

php artisan vendor:publish --provider="vildanbina\Revisions\ServiceProvider" --tag="migrations"

在迁移文件发布后,您可以通过运行以下命令创建 revisions

php artisan migrate

设置

步骤 1

您的 Eloquent 模型应使用 vildanbina\Revisions\Traits\HasRevisions 特性和 vildanbina\Revisions\Options\RevisionOptions 类。

该特性包含一个抽象方法 getRevisionOptions(),您必须自行实现。

以下是一个如何实现特例的示例

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use vildanbina\Revisions\Options\RevisionOptions;
use vildanbina\Revisions\Traits\HasRevisions;

class YourModel extends Model
{
    use HasRevisions;

    /**
     * Get the options for revisioning the model.
     *
     * @return RevisionOptions
     */
    public function getRevisionOptions(): RevisionOptions
    {
        return RevisionOptions::instance();
    }
}
步骤 2

revisions.php 配置文件中,将您的 User 模型类的完整命名空间写入 user_model 配置键。

默认情况下,此值为 Laravel 的 User 模型类的完全限定名(\App\User)。如果您应用程序没有用户的概念,也可以将其留为 NULL

这部分用于 vildanbina\Revisions\Traits\HasRevisions 特性来识别哪个用户创建了哪些修订版本。

使用

获取修订版本

您可以通过使用存在于 vildanbina\Revisions\Traits\HasRevisions 特性上的 revisions 多对多关系来获取模型记录的修订版本。

$model = YourModel::find($id);

$revisions = $model->revisions;
创建修订版本(自动)

一旦您在 Eloquent 模型中使用了 vildanbina\Revisions\Traits\HasRevisions 特性,每次更新模型记录时,都会自动创建包含其原始属性值的修订版本,使用 updated Eloquent 事件

// model is state 1
$model = YourModel::find($id);

// model is state 2
// a revision containing the model's state 1 is created 
$model->update(...);

或者,您还可以使用 created Eloquent 事件通过使用 create 创建新模型记录时存储每个修订版本
(见 自定义

创建修订版本(手动)

如果您需要,您还可以通过使用 saveAsRevision() 方法从 vildanbina\Revisions\Traits\HasRevisions 特性手动创建修订版本

$model = YourModel::find($id);

// a new entry is stored inside the 'revisions' database table
// reflecting the current state of that model record
$model->saveAsRevision();
回滚到以前的修订版本

您可以使用 rollbackToRevision() 方法将模型记录回滚到其以前的某个修订版本。

// model is state 1
$model = YourModel::find($id);
$revision = $model->revisions()->latest()->first();

// model is now in state 0
$model->rollbackToRevision($revision);

自定义

在创建时启用修订版本

默认情况下,在创建新的模型记录时,不会创建修订版本,因为记录是全新的,处于初始状态。但是,如果您希望在创建模型记录时创建修订版本,可以通过在 getRevisionOptions() 方法的定义中使用 enableRevisionOnCreate() 方法来实现。

/**
 * Get the options for revisioning the model.
 *
 * @return RevisionOptions
 */
public function getRevisionOptions(): RevisionOptions
{
    return RevisionOptions::instance()
        ->enableRevisionOnCreate();
}
限制修订版本数量

您可以通过在 getRevisionOptions() 方法的定义中使用 limitRevisionsTo() 方法来限制每个模型记录可以拥有的修订版本数量。

这可以防止某个频繁更新的记录有数千个修订版本。

当达到限制时,在创建新(最新)修订版本后,脚本将自动删除最旧的修订版本。

/**
 * Get the options for revisioning the model.
 *
 * @return RevisionOptions
 */
public function getRevisionOptions(): RevisionOptions
{
    return RevisionOptions::instance()
        ->limitRevisionsTo(100);
}
仅修订某些字段

如果您不想修订模型的所有字段(属性),可以通过在 getRevisionOptions() 方法的定义中使用 fieldsToRevision() 方法手动指定在创建新修订版本时希望存储的字段。

请注意,省略的字段在创建修订版本时不会存储,但在回滚到修订版本时,这些忽略的字段将变为实际模型记录的 null / 空值。

/**
 * Get the options for revisioning the model.
 *
 * @return RevisionOptions
 */
public function getRevisionOptions(): RevisionOptions
{
    return RevisionOptions::instance()
        ->fieldsToRevision('title', 'content');
}
排除某些字段进行修订

fieldsToRevision() 方法相反,如果您在修订 Eloquent 模型时想排除某些字段,请在 getRevisionOptions() 方法的定义中使用 fieldsToNotRevision() 方法。

请注意,fieldsToRevision() 的优先级高于 fieldsToNotRevision()
不要在同一个 getRevisionOptions 方法的定义中使用这两种方法。

请注意,省略的字段在创建修订版本时不会存储,但在回滚到修订版本时,这些忽略的字段将变为实际模型记录的 null / 空值。

/**
 * Get the options for revisioning the model.
 *
 * @return RevisionOptions
 */
public function getRevisionOptions(): RevisionOptions
{
    return RevisionOptions::instance()
        ->fieldsToNotRevision('title', 'content');
}
创建修订版本时包含时间戳

默认情况下,在创建修订版本时,实际模型的时间戳会自动从实际修订数据中排除。

如果您想在创建修订版本时存储模型的时间戳,请使用 getRevisionOptions() 方法的定义中的 withTimestamps() 方法。

/**
 * Get the options for revisioning the model.
 *
 * @return RevisionOptions
 */
public function getRevisionOptions(): RevisionOptions
{
    return RevisionOptions::instance()
        ->withTimestamps();
}
与模型记录一起修订关系

通常情况下,您会想创建一个模型记录的时间点完整副本,这包括修订其关系(特别是子关系)。

您可以通过在 getRevisionOptions() 方法的定义中使用 relationsToRevision() 方法来指定与模型记录一起修订的关系。

请注意,当回滚模型记录到过去修订版本时,指定的关系也将回滚到该修订发生时的状态(这包括从头开始重新创建在过程中强制删除的关系记录,或删除直到修订检查点之前添加的任何相关记录)。

/**
 * Get the options for revisioning the model.
 *
 * @return RevisionOptions
 */
public function getRevisionOptions(): RevisionOptions
{
    return RevisionOptions::instance()
        ->relationsToRevision('comments', 'author');
}
禁用回滚时创建修订版本

默认情况下,当回滚到过去修订版本时,会自动创建一个新的修订版本。这个新修订版本包含回滚发生前的模型记录状态。

您可以通过在 getRevisionOptions() 方法的定义中使用 disableRevisioningWhenRollingBack() 方法来禁用此行为。

/**
 * Get the options for revisioning the model.
 *
 * @return RevisionOptions
 */
public function getRevisionOptions(): RevisionOptions
{
    return RevisionOptions::instance()
        ->disableRevisioningWhenRollingBack();
}

事件

修订功能包含两个 Eloquent 事件:revisioningrevisioned

您可以在 Eloquent 模型中实现这些事件,就像实现 Laravel 框架附带的其他任何 Eloquent 事件一样。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use vildanbina\Revisions\Options\RevisionOptions;
use vildanbina\Revisions\Traits\HasRevisions;

class YourModel extends Model
{
    use HasRevisions;

    /**
     * Boot the model.
     *
     * @return RevisionOptions
     */
    public static function boot()
    {
        parent::boot();

        static::revisioning(function ($model) {
            // your logic here
        });

        static::revisioned(function ($model) {
            // your logic here
        });
    }
    
    /**
     * Get the options for revisioning the model.
     *
     * @return RevisionOptions
     */
    public function getRevisionOptions(): RevisionOptions
    {
        return RevisionOptions::instance();
    }
}

致谢

安全

如果您发现任何安全相关的问题,请通过电子邮件 vildanbina@gmail.com 而不是使用问题跟踪器。

许可证

MIT 许可证(MIT)。请参阅 LICENSE 获取更多信息。

变更日志

请参阅 CHANGELOG 获取有关最近更改的更多信息。

贡献

请参阅 CONTRIBUTING 获取详细信息。