camilo-manrique/laravel-filter

基于URL查询的Eloquent模型过滤

1.3.0 2019-02-24 23:42 UTC

This package is auto-updated.

Last update: 2024-09-29 03:52:44 UTC


README

Latest Stable Version License Build Status

此软件包允许根据URL查询查询Eloquent模型。使用一些简单的规则,您甚至可以根据相关模型进行过滤并使用不同的SQL比较运算符。

安装

使用composer安装包

```
composer require camilo-manrique/laravel-filter
```

将CamiloManrique\LaravelFilter添加到您的config/app.php中的服务提供者

'providers' => [
    CamiloManrique\LaravelFilter\FilterServiceProvider::class
]

您可以通过发布配置文件来更改默认设置

php artisan vendor:publish

根据您的数据库列名和个人偏好,您可能需要更改一些默认设置。

使用方法

此软件包向Builder类添加了两个宏方法,允许在不进行任何进一步设置的情况下使用过滤方法。这两个方法都可以接收HttpRequest、Collection或数组作为参数。下面将解释这两个方法。

关于方法名的说明:如果Builder类的宏方法存在命名冲突,可以在配置文件中自定义宏方法名称。以下示例将使用默认名称。

获取查询构建器实例

User::filter($request)

使用此方法,您可以获取一个查询构建器实例,在其中可以继续应用查询构建器方法,包括get()first()paginate()等。

获取模型实例

User::filterandGet($request)

此方法为您处理查询构建和检索。它甚至可以开箱即用地处理分页。默认情况下,使用此方法自动启用分页,但您可以通过发布配置文件并对其进行编辑来更改此行为。

这些方法也可以不带参数调用,在这种情况下,不会将任何过滤器应用于查询。

由于这些方法是Builder类的宏,因此在使用相关模型时也可以进行链式调用。例如,假设模型User与Post模型有关联,您可以使用如下方式

$user = User::find(1)
$user->posts()->filterAndGet($request);

实用示例

从路由返回

Route::get('/users', function(){
    return User::filterAndGet(request());
});

从控制器返回

public function index(Request $request){
    return User::filterAndGet($request);
}

关于Eloquent API资源的说明:如果您正在使用Laravel 5.5,您还可以使用此软件包与Eloquent Resources的新功能一起使用。

Route::get('/users', function(){
    return UserResource::collection(User::filterAndGet(request()));
});

过滤规则

现在,这是一个重要的部分。我们已经解释了如何安装和调用过滤方法,但您如何定义实际的过滤器?对于基本查询来说,这相当简单;如果需要根据相关模型进行查询,则可能需要更多说明。

定义过滤列

在您的请求中,只需使用列名作为键,比较值作为值。

示例

假设您的应用URL是http://www.example.com,您定义了一个路由/users,该路由指向一个名为filter的控制器方法,如下所示

    namespace App\Http\Controllers;
    
    use App\Users;
    
    class UsersController extends Controller
    {
        public function filter(Request $request)
        {
            return User::filterAndGet($request);
        }
    }

假设您想要检索来自德国的用户。您的HttpRequest对象应该有一个名为country的键,其值设置为Germany。URI请求将如下所示

    http://www.example.com/users?country=Germany

现在假设您想更具体一些,您想要检索不仅来自德国,而且是男性的用户。您的URI将变成如下所示

    http://www.example.com/users?country=Germany&gender=Male

请记住,您也可以使用Collections和数组传递所需的过滤器。最后一个示例使用数组作为参数的等效方式如下

    $filters = ["country" => "Germany", "gender" => "Male"]
    User::filterAndGet($filters);

查询比较运算符

以上示例仅适用于精确匹配,但您可能需要一个更宽松的比较,如 >、<、LIKE 和 != 运算符提供的比较。为了使用这些运算符,您需要在列名末尾附加一个关键字,并用 '/' 字符分隔。这个分隔字符可以在配置文件中更改。

以下列出了关键字及其对应运算符

  • start: >= value
  • end: <= value
  • like: LIKE %value%
  • not: != value

示例

检索来自德国且年龄小于30岁的用户

    http://www.example.com/users?country=Germany&age%2Fend=30

在上面的示例中,%2F 是 '/' 字符的编码。

使用数组作为参数的等效形式

    $filters = ["country" => "Germany", "age/end" => 30]
    User::filterAndGet($filters);

高级用法

将相关模型添加到响应中

有时您可能需要从查询中检索额外的相关模型。您可以通过在输入中添加关键字 "relationships" 并将其值设置为以逗号分隔的关系列表(如您的模型类中定义的,而不是表名)来实现这一点。

如果您在模型中有一个名为 "relationships" 的列,则过滤器将表现异常。在这种情况下,请在配置文件中更改搜索关键字数组中的关系键,并将其值更改为任何不会与您的列名冲突的其他单词。

例如,假设您有一个包含两个相关模型 Posts 和 Comments 的 User 模型,这些模型之间存在一对一的关系(一个用户可以有多个 Posts 和 Comments)。现在,您只想获取来自德国的用户,但您想在响应中包含这些用户的帖子。输入如下所示

    $filters = ["country" => "Germany", "relationships" => "posts,comments"]
    User::filterAndGet($filters);

这样,每个用户的 Posts 和 Comments 模型都会包含在响应中。

当加载具有许多模型的关联时,请小心,因为它们都会被加载,可能导致响应时间非常慢。

基于相关模型进行筛选

正如您可以在结果中包含相关模型一样,您也可以根据相关模型筛选结果。您只需要在列名前添加关系和一个 "@" 字符。例如,假设一个 User 模型有一个名为 "account_info" 的一对一关系,与名为 AccountInfo 的模型相关联,并且这个模型有一个名为 "name" 的属性。要基于用户模型对 AccountInfo 模型的 "name" 列进行筛选,输入如下

    $filters = ["account_info@name" => "John"]
    User::filterAndGet($filters);

获取总和聚合

有时,您可能不需要查询的实际模型。相反,您可能需要获取一个或多个属性的总和。在这种情况下,您应该在输入中添加关键字 "sum",并将其值设置为要获取总和的列或列(列应以逗号分隔)。例如,获取某些用户帖子的总投票数

    $filters = ["user_id" => 1, sum" => "votes"]
    User::filterAndGet($filters);

另一种选择是使用 Eloquent 关系方法

    $user = User::find(1)
    $filters = ["sum" => "votes"]
    $user->posts()->filterAndGet($filters);