camilo-manrique / laravel-filter
基于URL查询的Eloquent模型过滤
Requires
- php: >=7.0.0
- illuminate/config: 5.*
- illuminate/database: 5.*
- illuminate/support: 5.*
Requires (Dev)
- fzaninotto/faker: ~1.4
- mockery/mockery: 0.9.*
- orchestra/database: ~3.5.0
- orchestra/testbench: ~3.0
- phpunit/phpunit: ~6.0
README
此软件包允许根据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);