mustafaomar/laravel-qsw

根据查询字符串参数在查询构建器上干净地应用过滤器。

v1.1.0 2023-07-02 22:28 UTC

This package is auto-updated.

Last update: 2024-09-15 18:22:33 UTC


README

根据查询字符串参数在查询构建器上干净地应用过滤器。

有时您可能想在查询构建器上应用额外的逻辑,例如:加载一些关系,以便您可以根据查询字符串参数返回这些关系,或者您可能想应用复杂的过滤器,例如:status=active&with=comments,replies&from=2000-01-10&to=2022-05-25&sort=newest等。

此包以极佳的方式简化了这一过程。

使用此包的主要目标是分离关注点,我们不想在控制器中有大量的行。

安装

您可以通过 composer 安装它。

$ composer require mustafaomar/laravel-qsw

使用方法

有几种方法可以开始使用 laravel-qsw

可作用域特性

您可以在模型中使用 Scopable 并完成设置,您现在可以访问 watch 作用域,示例。

Article.php

use QueryWatcher\Traits\Scopable;

class Article extends Model
{
    use HasFactory, Scopable;
}

我们需要做的最后一步是创建一个作用域,您可以使用以下命令完成。

按照惯例,请使用模型名称,然后是您想监视的查询参数,最后是 Scope,例如 ?status=success 将会是 ArticleStatusScope

php artisan make:scope ArticleStatusScope

此命令将创建一个类似以下的作用域类

namespace App\Scopes;
 
use QueryWatcher\Contracts\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
 
class ArticleStatusScope implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param \Illuminate\Database\Eloquent\Builder $builder
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        //
    }
}

实际应用场景

现在让我们通过实际例子来创建一个描述如何使用实际数据过滤的示例。

ArticleController.php

public function index(Request $request)
{
    $article = Article::watch($this->queryWatchers())->first();

    return response()->json($article);
}

protected function queryWatchers()
{
    return [
        // 'comments' => ArticleCommentScope::class,
        // Notice: sometimes you may want to apply the scope
        // when two query parameters are presented, you can do this with:
        'when:from,to' => ArticleRangeScope::class,
        'sort' => ArticleSortScope::class
    ];
}

在这个作用域中,我们将过滤日期范围内的记录。

class ArticleRangeScope implements Scope
{
    public $from;

    public $to;

    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param \Illuminate\Database\Eloquent\Builder $builder
     * @param string|number $value
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        $builder->whereBetween('created_at', [$this->from, $this->to]);
    }
}

// Sort scope

class ArticleSortScope implements Scope
{
    public $sort;

    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param \Illuminate\Database\Eloquent\Builder $builder
     * @param string|number $value
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        if ($this->sort === 'newest') {
            $builder->latest();
        } else if ($this->sort === 'oldest') {
            $builder->oldest();
        }

        // ...
    }
}

高级

如果您出于某些原因不想使用 watch 关键字作为作用域,您可以创建自己的本地 scope

以下示例中我们将创建一个名为 scopes 的作用域。

Article.php

use QueryWatcher\Facades\QueryWatcher;
use Illuminate\Database\Eloquent\Builder;

class Article extends Model
{
    use HasFactory;

    /**
     * Register the query string params to watch
     * 
     * @param \Illuminate\Database\Eloquent\Builder  $builder
     * @param array  $scopes
     * @return  \Illuminate\Database\Eloquent\Builder
     */
    public function scopeScopes(Builder $builder, $scopes)
    {
        $instance = QueryWatcher::getInstance();

        // Or by resolving query watcher from the container

        $instance = app('laravel.qsw');

        $instance->watch($builder, $scopes);

        return $builder;
    }
}

请不要将作用域与 Scopes 混淆,scope 是一个告诉 Laravel 我们想要使用后缀 Scopes 的单词,在构建查询时调用。

$article = Article::scopes([])->first();