为 Laravel 5.5 中的所有模型制作自定义查询生成器方法(查询范围)

Make custom query builder method (query scope) for all models in Laravel 5.5

我有多个模型,都带有时间戳。我经常使用 whereDate 来获取今天和昨天的所有行,如下所示:

ModelName::whereDate('created_at', now()->today())->get();
ModelName::whereDate('created_at', now()->yesterday())->get();

我想让它更短、更简单,例如:

ModelName::today()->get();
ModelName::yesterday()->get();

我找不到任何方法来做到这一点,所以我在文档中发现我可以自己制作 "scopes"。问题是,我可以为指定的模型制作它,但我找不到一种方法可以在全球范围内为所有模型制作它。现在我需要在每个模型 class 中粘贴此范围方法。这行得通,但我需要在每个模型 class 中重复此代码,所以我敢肯定这不是一个好方法。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class ModelName extends Model
{


    /**
     * Custom scope (query builder method) to easy return all items from today
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeToday($query)
    {
        return $query->whereDate('created_at', now()->today());
    }


    /**
     * Custom scope (query builder method) to easy return all items from yesterday
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeYesterday($query)
    {
        return $query->whereDate('created_at', now()->yesterday());
    }
}

您可以在特征中定义 local scopes

<?php
namespace App\Traits;

trait Scopes
{
    public function scopeToday($query)
    {
        return $query->whereDate('created_at', now()->today());
    }

    public function scopeYesterday($query)
    {
        return $query->whereDate('created_at', now()->yesterday());
    }
}

然后在您喜欢的任何模型中使用该特征:

use App\Traits\Scopes;

并使用特征:

ModelName::today()->get();
ModelName::yesterday()->get();

另一种方法是创建和扩展基础模型 class 并在那里定义范围,但我会使用特征。

如果您不想更改任何模型,但仍要为所有模型获取一个方法,请使用 micros :

\Illuminate\Database\Eloquent\Builder::macro('test',function (){
    $this->dd();
});

现在您可以拨打AnyModel::test()