mustafaomar / laravel-qsw
根据查询字符串参数在查询构建器上干净地应用过滤器。
v1.1.0
2023-07-02 22:28 UTC
Requires
- php: >=7.2.5
- laravel/framework: ~7.0 || ~8.0 || ~9.0 || ~10.0
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();