marwanmg / eloquent-filter-custom
一个简单的Eloquent过滤器,用于简化API过滤,支持使用或操作搜索
Requires (Dev)
- orchestra/testbench: ^4.0 || ^5.0 || ^6.0 || ^7.0
This package is auto-updated.
Last update: 2024-09-21 13:29:16 UTC
README
Laravel Legends Eloquent Filter
一个有用的库,用于为Eloquent创建过滤器。
此库可用于在Eloquent的帮助下创建Rest API的搜索过滤器。
🇧🇷🚀🚀🚀
描述
Eloquent Filter库可用于在您的Laravel项目中创建模型上的搜索条件模式。想法是简单地通过请求负载中的值来聚合过滤器。
安装
为了安装,您应该使用Composer。运行以下命令
composer require marwanmg/eloquent-filter-custom
使用指南
LaravelLegends\EloquentFilter\Concerns\HasFilter
特质可以用于将搜索过滤器应用于模型的模型。
use LaravelLegends\EloquentFilter\Concerns\HasFilter; class User extends Model { use HasFilter; }
HasFilter
特质提供了filter
和withFilter
方法。
在您的Laravel应用程序中使用此库的简单方法是,在获取模型结果之前调用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
。
URL 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: 'https://:8000/api' }); api.get('users', { params: { 'in[role]' : [1, 2, 3], 'contains[name]' : 'Maxters', 'is_null[name]' : 0 } })
分叉版本更新
以下是此分叉版本中的新更新
contains 或
URL api/users?contains[name,name_en]=tomato
好像是一个
User::where('name', 'LIKE', '%value%')->orWhere('name_en', 'LIKE', '%value%');
并且可以添加更多列
URL api/users?contains[name,name_en,name_fr]=tomato
好像是一个
User::where('name', 'LIKE', '%value%')->orWhere('name_en', 'LIKE', '%value%')->orWhere('name_fr', 'LIKE', '%value%');