首页 > 解决方案 > 如何按日期顺序确定记录的编号

问题描述

在我的 Laravel 项目中,我有一个Policy看起来像这样的模型:


<?php

namespace App;

use App\Notifications\PolicyRequiresApproval;
use Illuminate\Database\Eloquent\Model;

class Policy extends Model
{
    const STATUS_PUBLISHED = 'published';
    const STATUS_PENDING_REVIEW = 'pending review';
    const STATUS_SENT_FOR_REVIEW = 'sent for review';
    const STATUSES = [
        self::STATUS_PENDING_REVIEW,
        self::STATUS_PUBLISHED,
    ];

    /**
     * The attributes that are mass assignable.
     */
    protected $fillable = [
        'id', 'user_id', 'name', 'content', 'status',
    ];

    /**
     * The user who authored the policy.
     */
    public function author()
    {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }

    /**
     * Get all of the audits for this policy.
     */
    public function audits()
    {
        return $this->hasMany(PolicyAudit::class, 'policy_id', 'id')->orderBy('created_at', 'desc');
    }

    /**
     * Get all of the versions for this policy.
     */
    public function versions()
    {
        return $this->hasMany(PolicyVersion::class, 'policy_id', 'id');
    }

    /**
     * Get the current version.
     */
    public function currentVersion()
    {
        return $this->versions()->orderBy('created_at', 'DESC')->first();
    }

    /**
     * Get the most recent approved version.
     */
    public function currentApprovedVersion()
    {
        return $this->versions()
            ->whereNotNull('approved_at')
            ->orderBy('created_at', 'DESC')
            ->first();
    }

    /**
     * Get the URL to preview the policy for administrators.
     */
    public function getPreviewUrlAttribute()
    {
        return route('thanos.policies.show', $this);
    }

    /**
     * Send a policy to the policy administrator for approval.
     */
    public function sendForReview(Policy $policy)
    {
        User::role(['admin'])->get()
        ->each(function ($user) use ($policy) {
            $user->notify((new PolicyRequiresApproval($policy))->delay(now()->addSeconds(10)));
        });

        $this->update(['status' => self::STATUS_SENT_FOR_REVIEW]);
    }
}

如您所见,有策略的版本。

我的策略版本表架构如下所示:


<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePolicyVersionsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('policy_versions', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('policy_id');
            $table->unsignedBigInteger('user_id')->nullable();
            $table->longText('values');
            $table->boolean('is_major_change')->default(0);
            $table->dateTime('approved_at')->nullable();
            $table->unsignedBigInteger('approved_by')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('policy_versions');
    }
}


我的问题如下:如果我有五个按日期顺序排列的政策版本,并且我选择了一个政策版本,我怎么能说“你在这个政策的 x 版本上”?

policy_version_number每次创建新版本时最好添加一个并增加它吗?

这感觉像是一个愚蠢的问题,但最初我只是打算使用版本 ID,但这实际上是不正确的。

标签: phplaraveleloquent

解决方案


您可以侦听模型的事件并在创建模型时自动填充列。为此,请boot在模型中实现该方法PolicyVersion

public static function boot() {
    parent::boot();

    static::creating(function (PolicyVersion $item) {
        $max = PolicyVersion::where('policy_id', $item->id)->max('policy_version_number');
        $item->policy_version_number = $max + 1;
    });
}

未经测试,但应该可以解决问题。


推荐阅读