travelbuild/eloquent-filterable

使用动态Eloquent作用域进行搜索过程

v1.0.1 2019-05-30 12:48 UTC

This package is auto-updated.

Last update: 2024-08-29 05:00:29 UTC


README

使用本包,您可以使用filter作用域方法调用本地作用域。

安装

需要PHP 7.1.3+或HHVM,以及Composer。

要获取此包,只需将以下行添加到您的composer.json文件的require块中

"require": {
    "travelbuild/eloquent-filterable": "~1.0"
}

然后,您需要运行composer install或composer update来下载它并更新自动加载器。或者,您也可以通过终端使用快捷方式安装

composer require travelbuild/eloquent-filterable

使用方法

每个模型都必须实现Filterable特性。

<?php

namespace App;

use Travelbuild\Filterable\Filterable;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use Filterable;
}

然后,您可以在模型中定义本地作用域。如果您需要关于本地作用域的帮助,请参阅Laravel文档

/**
 * Scope a query to only include only active posts.
 *
 * @param  Builder  $query
 * @return Builder
 */
public function scopeActive(Builder $query): Builder
{
    return $query->where('active', true);
}

最后,如果您需要,必须在模型中将可用的本地作用域定义为filterable属性。为什么需要它?我们不想让一些作用域被客户端使用。

/**
 * The usable scope filters.
 *
 * @return array
 */
protected $filterable = [
    'active',
];

如果您想让所有作用域都可供客户端使用,请不要定义filterable属性或按如下方式定义

这种方式不推荐。请掌握控制权,访问所有作用域可能会有风险。

/**
 * The usable scope filters.
 *
 * @return array
 */
protected $filterable = ['*'];

这就对了。现在,您可以使用filter作用域动态调用所有可调用的作用域。

$users = User::filter(['active' => true])->paginate();

真实世界示例

我们需要这个包来快速响应HTTP请求。我们的客户端通过搜索端点发送了一些条件。我们希望为了简单性和可重用性,动态地处理这些过滤器条件。

<?php

namespace App\Http\Controllers;

use App\Post;
use Illuminate\Http\Request;

class PostSearchController extends Controller
{
    /**
     * Respond the post search request.
     *
     * @param  Request  $request
     * @return JsonResponse
     */
    public function __invoke(Request $request)
    {
        $posts = Post::filter($request->all())->paginate(
            $request->get('limit', 25)
        );

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

routes/api.php中创建一个新路由进行POST搜索

Route::get('/posts', 'PostSearchController');

定义模型和filterable本地作用域

<?php

namespace App;

use Travelbuild\Filterable\Filterable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class Post extends Model
{
    use Filterable;

    /**
     * The usable scope filters.
     *
     * @return array
     */
    protected $filterable = [
        'active',
        'author',
    ];

    /**
     * Scope a query to only include only active posts.
     *
     * @param  Builder  $query
     * @return Builder
     */
    public function scopeActive(Builder $query): Builder
    {
        return $query->where('active', true);
    }

    /**
     * Scope a query to only include author's posts.
     *
     * @param  Builder  $query
     * @param  int  $authorId
     * @return Builder
     */
    public function scopeAuthor(Builder $query, int $authorId): Builder
    {
        return $query->where('author_id', $authorId);
    }
}

现在,客户端可能会向服务器发送一些搜索条件。以下是一些示例端点

/posts
/posts?active
/posts?author=5
/posts?active&author=5
/posts?active&author=5&limit=10
...

当存在本地作用域时,我们的模型将应用过滤器。

贡献

热爱创新和简洁。请使用问题报告所有错误或建议。遵循贡献步骤

  1. 分支存储库。
  2. 遵循Laravel编码风格
  3. 如果需要,请使用unittest检查您的更改。
  4. 提交所有更改。
  5. 提交您的更改并创建一个新的PR。
  6. 等待合并PR。

单元测试

请创建您的测试并在PR之前进行检查。使用以下命令

$ phpunit

许可协议

Eloquent Filterable遵循MIT许可协议(MIT)