proai/eloquent-versioning

一个用于支持版本控制的Eloquent ORM扩展。

1.0.7 2018-05-24 16:37 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:14:54 UTC


README

Latest Stable Version Total Downloads Latest Unstable Version License

这是一个用于支持版本控制的Eloquent ORM扩展。您可以指定属性作为版本化。如果属性被指定为版本化的,则其值将在每次更新时保存在一个单独的版本表中。该功能可以使用时间戳和软删除。

安装

Eloquent Versioning是一个composer包。因此,您首先需要将包添加到您的composer.json文件中。

"proai/eloquent-versioning": "~1.0"

然后,您必须运行composer update来安装该包。

示例

假设我们想要一个简单的用户模型。虽然用户名应该是固定的,但电子邮件和城市应该是可版本化的。此外,时间戳和软删除也应该版本化。迁移将如下所示

...

Schema::create('users', function(Blueprint $table) {
    $table->increments('id');
    $table->integer('latest_version');
    $table->string('username');
    $table->timestamp('created_at');
});

Schema::create('users_version', function(Blueprint $table) {
    $table->integer('ref_id')->primary();
    $table->integer('version')->primary();
    $table->string('email');
    $table->string('city');
    $table->timestamp('updated_at');
    $table->timestamp('deleted_at');
});

...

引用的Eloquent模型应包括以下代码

<?php

namespace Acme\Models;

use Illuminate\Database\Eloquent\Model;
use ProAI\Versioning\Versionable;
use ProAI\Versioning\SoftDeletes;

class User extends Model
{
    use Versionable, SoftDeletes;
    
    public $timestamps = true;
    
    public $versioned = ['email', 'city', 'updated_at', 'deleted_at'];
    
    ...
}

用法

数据库表

您需要将以下列添加到主模型表中

  • latest_version (整数)。

此外,您需要一个版本表。版本表的名字与主模型表的名字相同(例如,对于模型表users,名字将是users_version)。这个表必须包含以下列

  • ref_后跟模型主键的名字(如果主键是id,列名将是ref_id
  • version (整数)

Eloquent模型

您必须在模型中定义一个$versioned数组,它包含所有版本化列。

数据库查询

查询数据库

默认情况下,查询构建器将检索最新版本(例如,User::find(1);将返回用户#1的最新版本)。如果您想获取特定版本或所有版本,可以使用以下方法

  • version(VERSION_NO)返回特定版本
    示例:User::version(2)->find(1)将返回用户#1的第2版

  • allVersions()返回查询项的所有版本
    示例:User::allVersions()->get()将返回所有用户的全部版本

  • moment(Carbon)返回特定版本,最接近但低于输入日期的版本
    示例:User::moment(Carbon::now()->subWeek()->find(1)将返回那个时间点的版本。

创建、更新和删除记录

所有这些操作都可以正常执行。包将在创建时自动生成版本1,更新时生成下一个版本,在删除时删除所有版本。

时间戳

您可以使用两种方式使用时间戳。对于两种方式,您都必须设置$timestamps = true;

  • 正常时间戳
    主表必须包含一个created_at和一个updated_at列。在每次更新时,updated_at列将被覆盖。因此,这是Eloquent时间戳的正常用法。

  • 版本化时间戳
    如果您将updated_at添加到您的$versioned数组中,您需要在主表中有一个created_at列和一个版本表中的updated_at列(见示例)。在更新时,新版本的updated_at值将设置为当前时间。前一个版本的updated_at值不会更新。这样,您可以跟踪所有更新日期。

软删除

如果您使用带软删除的 Versionable 特性,您必须使用本包中的 ProAI\Versioning\SoftDeletes 特性,而不是使用 Eloquent 的软删除特性。

  • 普通软删除
    只需在主表中使用一个 deleted_at 列。然后在删除或恢复时,deleted_at 的值将被更新。

  • 版本化软删除
    如果您在版本表中创建一个 deleted_at 列,并将 deleted_at 添加到 $versioned 数组中,那么在删除或恢复时,新版本的 deleted_at 值将得到更新(见示例)。先前版本的 deleted_at 值将不会被更新。这样,您可以跟踪所有软删除和恢复操作。

自定义查询构建器

如果您想使用自定义版本化查询构建器,您将不得不构建自己的版本化特性,但这非常简单。

<?php

namespace Acme\Versioning;

trait Versionable
{
    use \ProAI\Versioning\BaseVersionable;
    
    public function newEloquentBuilder($query)
    {
        return new MyVersioningBuilder($query);
    }
}

显然,您必须将 MyVersioningBuilder 替换为您的自定义构建器的类名。此外,您必须确保您的自定义构建器实现了版本化查询构建器的功能。有一些策略可以实现这一点

  • 扩展版本化查询构建器 ProAI\Versioning\Builder
  • 使用版本化构建器特性 ProAI\Versioning\BuilderTrait
  • 将版本化查询构建器中的代码复制并粘贴到您的自定义构建器中

支持

错误和功能请求在 GitHub 上跟踪。

许可

本包根据 MIT 许可证 发布。