laravellegends / eloquent-filter
一个简单的Eloquent过滤器,用于简化API过滤
Requires (Dev)
- orchestra/testbench: ^4.0 || ^5.0 || ^6.0 || ^7.0
README
一个有用的库,用于为Eloquent创建过滤器。
此库有助于使用Eloquent在您的Rest API中创建搜索过滤器。
🇧🇷🚀🚀🚀
描述
Eloquent Filter库可用于在Laravel项目中创建模型上的搜索条件模式。想法是简单地将请求负载中的值传递以聚合过滤器。
安装
对于安装,您应该使用Composer。运行以下命令
composer require laravellegends/eloquent-filter
使用指南
可以在将应用搜索过滤器的模型中使用 LaravelLegends\EloquentFilter\Concerns\HasFilter
特性。
use LaravelLegends\EloquentFilter\Concerns\HasFilter; class User extends Model { use HasFilter; }
HasFilter
特性提供了 filter
和 withFilter
方法。
在获取模型结果之前调用 filter
方法是使用此库的简单方法。
示例
class UsersController extends Controller { use App\Models\User; public function index() { return User::filter()->paginate(); } // or public function index() { return User::latest('id')->filter()->paginate(); } // or public function index(Request $request) { return User::filter($request)->paginate(); } }
当调用 /api/users?exact[id]=1
时,将显示结果。SQL查询 "select * from users where (id = 1)"
将被应用。
注意:显示 规则 会提供更多信息。
另一种方法是使用特定于模型的过滤器。您可以通过继承ModelFilter类为模型创建自定义过滤器。
为了创建此类,您应该使用以下命令 php artisan make:filter
,如下例所示
$ php artisan make:filter UserFilter
上述命令将生成以下类
namespace App\Filters; use LaravelLegends\EloquentFilter\Filters\ModelFilter; class UserFilter extends ModelFilter { public function getFilterables(): array { return [ 'role_id' => 'not_equal', // or ['not_equal'] 'name' => ['contains', 'starts_with'], ]; } }
在控制器中
use App\Models\User; use Illuminate\Http\Request; use LaravelLegends\EloquentFilter\Filter; class UsersController extends Controller { // api/users?starts_with[name]=Wallace¬_equal[role_id]=2 public function index(Request $request) { return User::withFilter(new UserFilter, $request) ->orderBy('name') ->get(); } }
上述代码将内部调用如下示例
User::where(function ($query) { $query->where('name', 'LIKE', 'Wallace%'); $query->where('role_id', '<>', '2'); }) ->orderBy('name') ->get();
它做什么?
此库内部根据具有特殊关键字名称的查询字符串参数应用过滤器。
以下参数列表
max
列的最大值。URL api/users?max[field]=100
等同于 User::where('field', '<=', 100)
。
min
列的最小值。URL api/users?min[age]=33
等同于 User::where('age', '>=', 33)
。
contains
包含在列中的搜索词。URL api/users?contains[name]=wallace
等同于 User::where('name', 'LIKE', '%wallace%')
。
ends_with
根据字符串的结尾内容搜索值。类似于具有 %$value
值的 LIKE
。
starts_with
当值以特定值开始时筛选字段。URL api/users?starts_with[name]=brcontainer
看起来像 User::where('name', 'LIKE', 'brcontainer%')
。
exact
通过字段的精确值进行搜索。URL api/users?exact[email]=teste@teste.com
看起来像 User::where('name', '=', 'teste@teste.com')
。
has
通过关系进行筛选。您可以使用 0
或 1
值。
示例
URL api/users?has[posts]=1
等同于 User::has('posts')
。
URL api/users?has[posts]=0
等同于 User::doesntHave('posts')
。
is_null
将 WHERE IS NULL
或 WHERE IS NOT NULL
应用到查询中。
示例
URL api/users?is_null[cpf]=1
等同于 User::whereNull('cpf')
。
URL api/users?is_null[age]=0
等同于 User::whereNotNull('age')
。
not_in
当列没有传递的值时进行搜索。
示例
URL api/users?not_in[role][]=1¬_in[role][]=2
等同于 User::whereNotIn('role', [1, 2])
注意:当 not_in[my_field]
是空数组时,不会采取任何操作。
in
当列包含传递的值时进行搜索。
示例
URL api/users?in[role][]=10&in[role][]=20
类似于 User::whereIn('role', [10, 20])
注意:当 in[my_field]
是一个空数组时,不会执行任何操作。
date_max
按日期字段的最高值进行搜索。
URL api/users?date_max[created_at]=2021-01-01
类似于 User::whereDate('created_at', '<=', '2021-01-01')
date_min
按日期字段的最小值进行搜索。
示例
URL api/users?date_min[created_at]=2021-01-01
类似于 User::whereDate('created_at', '>=', '2021-01-01')
not_equal
按不等于传递的值进行搜索。如果你在相关字段中使用,将会应用 whereDoesntHave。
示例
URL api/users?not_equal[profile_id]=3
类似于
User::where('profile_id', '<>', '3');
URL api/users?not_equal[roles.id]=1
类似于
User::whereDoesntHave('roles', fn ($query) => $query->where('id', '=', 3));
year_max
URL api/users?year_max[created_at]=2000
类似于
User::whereYear('created_at', '<=', 2000);
year_min
URL api/users?year_min[created_at]=1998
类似于
User::whereYear('created_at', '>=', 1998);
year_exact
URL api/users?year_exact[created_at]=1998
类似于
User::whereYear('created_at', '=', 1998);
过滤关联字段
你可以在模型中定义的关联方法中应用搜索过滤器。
例如
模型
class User extends Model { use HasFilter; public function phones() { return $this->hasMany(Phone::class, 'user_id'); } }
过滤器
class UserFilter extends ModelFilter { public function getFilterables(): array { return [ 'id' => ['exact', 'not_equal'], 'created_at' => ['year_exact', 'date_max', 'date_min'], 'phones.number' => ['contains'], // or 'phones' => new PhoneFilter, ]; } } class PhoneFilter extends ModelFilter { public function getFilterables(): array { return [ 'number' => 'contains' ]; } }
class UserController extends Controller { public function index() { // api/users?not_in[role_id][]=1¬_in[role_id][]=3 // select * from users where (role_id NOT IN (1, 3)) return User::withFilter(new UserFilter)->paginate(); } // Or, apply filter as nested query public function index() { // api/users?exact[role_id]=1 // select * from users where (role_id = 1) return User::where(UserFilter::toClosure())->paginate(); } // Or apply in your query as base condition public function index() { // api/users?exact[role_id]=1 // select * from users where role_id = 1 return User::tap(UserFilter::toClosure())->paginate(); } }
在以下示例中,将根据包含值 55
的相关电话过滤用户。
api/users?exact[phones.number]=55
类似于
User::where(function ($query) { $query->whereHas('phones', function ($query) { $query->where('number', '=', '55'); }); })->paginate();
Axios 示例
如果你使用 axios
库,你可以使用 params
选项来包含上述过滤器。
示例
const api = axios.create({ baseURL: 'http://localhost:8000/api' }); api.get('users', { params: { 'in[role]' : [1, 2, 3], 'contains[name]' : 'Maxters', 'is_null[name]' : 0 } })