makeabledk/laravel-eloquent-status

v4.1.0 2024-06-01 09:42 UTC

README

Latest Version on Packagist Build Status StyleCI

查看解释此包概念的博客文章

https://medium.com/@rasmuscnielsen/an-eloquent-way-of-handling-model-state-c9aa372e9cb8

大多数模型都具有一定的状态或状态。以下是一些示例:

  • 帖子:草稿、私有、已发布
  • 工作:申请、接受、拒绝、完成、取消
  • 批准:待批准、审核中、批准

传统上,你可能会找到像scopeAccepted这样的作用域,然后额外添加一个isAccepted辅助方法来测试模型实例是否与特定状态匹配。

此包提供了一种处理此类状态而不使模型混乱的便捷方法。

当你成功设置此包后,你将能够实现如下语法:

Approval::status('approved')->get(); // Collection
$model->checkStatus('approved'); // bool

Makeable是一家位于丹麦奥尔胡斯的网络和移动应用程序代理机构。

安装

您可以通过composer安装此包

composer require makeabledk/laravel-eloquent-status

示例用法

基于我们之前提到的批准示例,我们可能有以下数据库字段

  • id
  • ... (一些外键)
  • tutor_approved_at
  • teacher_approved_at
  • assessor_approved_at
  • created_at
  • updated_at

让我们首先创建一个状态类,其中包含我们的状态定义

入门指南

1. 创建状态类

我们将定义所有有效状态为专用状态类中的公共函数。

<?php

class ApprovalStatus extends \Makeable\EloquentStatus\Status
{
    public function pending($query)
    {
        return $query
            ->whereNull('tutor_approved_at')
            ->whereNull('teacher_approved_at')
            ->whereNull('assessor_approved_at');
    }

    public function reviewing($query)
    {
        return $query
            ->whereNotNull('tutor_approved_at')
            ->whereNull('assessor_approved_at');
    }
    
    public function approved($query)
    {
        return $query
            ->whereNotNull('tutor_approved_at')
            ->whereNotNull('teacher_approved_at')
            ->whereNotNull('assessor_approved_at');
    }
}

请注意,状态定义就像常规scope函数一样。虽然这个例子非常简单,但你完全可以使用Eloquent查询构建器的全部功能!

提示:我们建议您的状态定义具有明确的定义,这意味着模型一次只能通过一个定义。这在接下来的几个步骤中会很有用。

2. 在模型上应用特性

<?php 
use \Makeable\EloquentStatus\HasStatus;

class Approval extends Eloquent 
{
    use HasStatus;
}

查询数据库

现在我们可以使用定义的状态查询数据库中的批准。

Approval::status(new ApprovalStatus('pending'))->get();

再次注意,这与我们习惯上调用作用域非常相似:Approval::pending()

然而,这种新方法有一些优点。

  • 我们已在一个地方定义和封装了所有状态,从而清理了模型
  • 我们可以仅针对有效状态进行查询
Approval::status(new ApprovalStatus('something-else'))->get(); // throws exception

例如,这使得从控制器中的GET过滤器安全地接受原始状态并返回结果变得方便,无需进一步验证或条件判断。

🔥检查模型状态

此包的真正魔力!

我们实际上可以使用相同的定义来检查模型实例是否符合给定的状态。

$approval->checkStatus(new ApprovalStatus('reviewing')); // true or false

这种魔法由我们的另一个包makeabledk/laravel-query-kit提供。

注意:请确保查看此readme的限制部分。

猜测模型状态

如果你想知道模型从其属性中哪个状态,那么你很幸运。

<?php 
use \Makeable\EloquentStatus\HasStatus;

class Approval extends Eloquent 
{
    use HasStatus;
    
    public function getStatusAttribute()
    {
        return ApprovalStatus::guess($this);
    }
}

现在$approval->status会尝试从你的定义中解析批准状态。

注意:状态是通过逐个检查定义来猜测的。这就是为什么你可能需要考虑明确的定义。

同时,您应该小心不要在定义中加载关系,并且通常考虑为大查询集使用缓存策略。

此外,请参阅本readme的限制部分。

将默认状态绑定到模型

每次执行检查时,您不需要传递状态类的实例,而是可以将默认状态类绑定到您的模型

use Makeable\EloquentStatus\StatusManager;

StatusManager::bind(Approval::class, ApprovalStatus::class);

现在您只需输入状态的名称即可

$approval->checkStatus('accepted'); 

除了默认状态以外的其他状态类仍然可以在显式传递时使用。

您可以在AppServiceProviderboot函数中绑定状态类,或者如果您愿意,可以创建一个单独的服务提供者。

限制

此包是在makeabledk/laravel-query-kit之上进行抽象的。

QueryKit提供了一个模拟的原生QueryBuilder版本,允许针对模型实例运行范围函数。

这种方法确保了出色的性能,无需数据库查询,但引入了某些限制。

虽然QueryKit支持大多数QueryBuilder语法,如闭包和嵌套查询,但它支持SQL语言,如连接和选择。这些限制仅适用于checkStatus()guess()函数。

有关更多信息,请参阅makeabledk/laravel-query-kit限制部分。

HasStatus上可用的方法

- scopeStatus($status)

Approval::status(new ApprovalStatus('approved'))->get(); // Collection

// Or when default status is defined
Approval::status('approved')->get(); // Collection

- scopeStatusIn($statuses)

Approval::statusIn(['pending', 'reviewing'])->get(); // Collection

- checkStatus

$approval->checkStatus('approved'); // bool

- checkStatusIn

$approval->checkStatusIn(['pending', 'reviewing']); // bool

测试

您可以使用以下命令运行测试:

composer test

贡献

我们很高兴接受为附加功能提供的拉取请求。请参阅CONTRIBUTING以获取详细信息。

鸣谢

许可

署名-相同方式共享 4.0 国际。有关更多信息,请参阅许可文件