sfneal/datum

使用自定义过滤器构建可重用和可缓存的 Eloquent 查询

2.0.2 2024-05-06 16:11 UTC

README

Packagist PHP support Latest Version on Packagist Build Status StyleCI Scrutinizer Code Quality Total Downloads

使用自定义过滤器构建可重用和可缓存的 Eloquent 查询。

安装

您可以通过 composer 安装此包。

composer require sfneal/datum

用法

基本查询

查询抽象类需要实现 builder() 方法,并且必须实现 execute() 方法。 builder() 方法检索用于构建查询的 Builder 实例(用于添加或删除作用域)。execute() 方法是添加查询其余参数的地方。期望的返回类型是 Builder,但可以重写为 Collection、数组、字符串等。在这种情况下,我们使用 HasKeyParam 在 Query 的 __construct 方法中接受 $modelKey 参数。

use Illuminate\Database\Eloquent\Builder;
use Sfneal\Queries\Query;
use Sfneal\Queries\Traits\HasKeyParam;

class PeopleQuery extends Query
{
    use HasKeyParam;
    
    /**
     * Retrieve a Query builder.
     *
     * @return Builder
     */
    protected function builder(): Builder
    {
        return People::query();
    }

    /**
     * Execute a DB query.
     *
     * @return Builder
     */
    public function execute(): Builder
    {
        return $this->builder()
            ->where('person_id', '=', $this->modelKey);
    }
}


// Example use
$model = (new PeopleQuery($id))->execute()->get()

高级查询(带过滤器)

FilterableQuery 抽象类扩展了之前提到的 Query 抽象类,并通过使用过滤器提供额外的功能。抽象 Query 所需的 execute 方法已预先定义,但必须实现 builder 方法。此外,FilterableQuery 还需要实现一个返回 Filter 类数组的方法,这些 Filter 类可用于向查询添加预定义的过滤器。

在创建 FilterableQuery 扩展之前,应该创建 Query 将使用的过滤器。

use Illuminate\Database\Eloquent\Builder;
use Sfneal\Filters\Filter;

class NameLastFilter implements Filter
{
    /**
     * Apply a given search value to the builder instance.
     *
     * @param Builder $query
     * @param mixed $value
     * @return Builder $query
     */
    public function apply(Builder $query, $value): Builder
    {
        $query->whereIn('name_last', (array) $value);

        return $query;
    }
}


class CityFilter implements Filter
{
    /**
     * Apply a given search value to the builder instance.
     *
     * @param Builder $query
     * @param mixed $value
     * @return Builder $query
     */
    public function apply(Builder $query, $value): Builder
    {
        $query->whereIn('city', (array) $value);

        return $query;
    }
}

现在我们已经创建了我们的过滤器,可以创建一个使用它们的 FilterableQuery 扩展。

use CityFilter;
use NameLastFilter;
use Sfneal\Queries\FilterableQuery;

class PeopleFilterableQuery extends FilterableQuery
{
    /**
     * Retrieve a Query builder.
     *
     * @return Builder
     */
    protected function builder(): Builder
    {
        return People::query();
    }

    /**
     * Retrieve an array of model attribute keys & corresponding Filter class values.
     *
     * @return array
     */
    protected function queryFilters(): array
    {
        return [
            'city' => CityFilter::class,
            'name_last' => NameLastFilter::class,
        ];
    }
}

FilterableQuery 最终创建后,我们可以传递过滤器参数并接收结果。

$filters = [
    'name_last' => 'Brady'
    'city' => 'Brookline',
];

$results = (new PeopleQueryWithFilters($filters))->execute()->get();

由于我们构建了 Filter 实现以将过滤器 $values 转换为数组,因此我们可以传递一个有效的过滤器数组以检索更多结果。

$filters = [
    'name_last' => [
        'Neal',
        'Brady',
    ],
    'city' => [
        'Brookline',
        'Boston',
    ],
];

$results = (new PeopleQueryWithFilters($filters))->execute()->get();

测试

composer test

变更日志

请参阅 CHANGELOG 以获取有关最近更改的更多信息。

贡献

请参阅 CONTRIBUTING 以获取详细信息。

安全性

如果您发现任何与安全性相关的问题,请通过电子邮件 stephen.neal14@gmail.com 而不是使用问题跟踪器。

鸣谢

许可

MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件

PHP 包模板

此包是使用 PHP 包模板 生成的。