您现在的位置是:网站首页 > PHP>Laravel 中 Eloquent 条件查询代码分离
Laravel 中 Eloquent 条件查询代码分离
- PHP
- 2019-01-18
- 456人已阅读
Eloquent 条件查询——tucker-eric/eloquentfilter
条件搜索在项目中是必不可少的功能,我们需要通过不同的请求数据,筛选出想要的数据,但是有时候你会发现查询条件很多的时候,Controller中的代码会越来越多,这时你可能会想优化一下这部分代码逻辑,tucker-eric/eloquentfilter 就是这样一个扩展包,可以帮助我们来优化搜索这部分代码逻辑。
场景分析
前台技术分享栏目控制器代码逻辑如下:
class TechnologyController extends Controller
{
public function index(Request $request,Technology $technology)
{
$query = $technology->query();
// 搜索标题
if ($title = $request->title) {
$query->where('title', 'Like', '%'.$title.'%');
}
// 搜索分类
if ($category_id = $request->category_id) {
$query->where('category_id', $category_id);
}
$query->where('created_at','<',date('Y-m-d H:i:s'));
// 排序规则
switch ($request->order) {
case 'asc':
$query->orderBy('id','asc');
break;
default:
$query->orderBy('sort','desc')->orderBy('created_at','desc')->orderBy('id','desc');
}
$list = $query->paginate(10);
return view('front.technology.index',['list'=>$list]);
}
但是随着业务的增加,会慢慢的增加各种筛选条件,这时控制的代码就会越来越多,这时就会想着把筛选部分给提出来,下面就是扩展包的介绍使用方法:
安装配置
$ composer require tucker-eric/eloquentfilter
安装成功后将配置文件发布出来,配置文件为 config/eloquentfilter.php 。
$ php artisan vendor:publish --provider="EloquentFilter\ServiceProvider"
tucker-eric/eloquentfilter 要求我们为针对不同的模型创建 Filter 类,统一放在某个文件中,默认的命名空间是 App\\ModelFilters\\ , 也就是会放在 app/ModelFilters 目录中。不是我的项目习惯模型都是放在 app/Models 下面,所以希望 Filter 文件也放在 app/Models/Filters 目录中,所以修改配置:
config/eloquentfilter.php
.
.
.
'namespace' => 'App\\Models\\Filters\\',
.
.
.
使用
创建 TechnologyFIlter
$ php artisan model:filter Technology
该命令会在 app/Models/Filters 目录中创建了 Technology 文件。
使用 Filterable Trait
接着需要让 Technology 模型使用 tucker-eric/eloquentfilter 提供 Trait EloquentFilter\Filterable :
app/Models/Technology
.
.
.
namespace App\Models;
use EloquentFilter\Filterable;
class Technology extends Model
{
use Filterable;
.
.
.
Filterable 提供了 filter 方法,当使用 Technology::filter() 方法的时候就会自动使用 Technology 这个类来帮助我们查询了。
修改 Controller
app/Http/Controllers/Front/TechnologyController.php
.
.
.
class TechnologyController extends Controller
{
public function index(Request $request, Technology $technology)
{
$list = $technology->filter($request->all())->paginate(20);
return view('front.technology.index',['list'=>$list]);
}
.
.
.
这里将之前的查询逻辑都删除了,只写了一句 $technology->filter($request->all()) ,将所有的请求参数传给 filter ,也就是 TechnologyFilter。
编写 TechnologyFilter 逻辑
我们将原来的 TechnologyController 中的查询逻辑都移到 TechnologyFilter 中:
app/Models/Filters/TechnologyFilter.php
.
.
.
namespace App\Models\Filters;
use EloquentFilter\ModelFilter;
class TechnologyFilter extends ModelFilter
{
public $relations = [];
public function title($value)
{
return $this->whereLike('title', $value);
}
public function category($id)
{
return $this->where('category_id',$id);
}
public function order($value)
{
switch ($value) {
case 'asc':
$this->orderBy('id','asc');
break;
default:
$this->orderBy('sort','desc')->orderBy('created_at','desc')->orderBy('id','desc');
break;
}
}
public function setup()
{
// 如果没有传 order,则默认使用 default
if (!$this->input('order')) {
$this->push('order', 'default');
}
}
}
上面的代码,其实每一个查询条件都会对应 Filter 类中的一个方法:
title ——标题—— function title;
category_id ——技术分类—— function category;
order ——排序方式—— function order ;
下划线分隔的参数会转换成驼峰,以 _id 结尾的参数会自动去除,然后对应方法,所以 category_id 会对应到 category 方法。每个方法的第一个参数就是对应请求参数的值。
我们将 Controller 中的大段查询条件代码,拆分到 filter 文件中的不同方法中,使得代码逻辑更加清晰,提高了代码的复用性,更有助于代码的维护。
这时再查询筛选发现与之前的结果一样。
在上面 title 的方法中使用的 whereLike 这里是 ElquentFilter 提供的方法。
EloquentFilter 提供的方法
$this->whereLike($column, $string) —— $query->where($column, 'LIKE', '%'.$string.'%')
$this->whereBeginsWith($column, $string) —— $query->where($column, 'LIKE', $string.'%')
$this->whereEndsWith($column, $string) —— $query->where($column, 'LIKE', '%'.$string)
有时候我们查询时候需要设置一些默认值, tucker-eric/eloquentfilter 其实已经考虑到了这样逻辑的时候,其实会执行 Technology 中的 setup 方法(如果这个方法存在),方便我们做一些初始化操作。
添加如下代码:
app/Models/Filters/TechnologyFilter.php
.
.
.
public function setup()
{
// 如果没有传 order,则默认使用 default
if (!$this->input('order')) {
$this->push('order', 'default');
}
}
.
.
.
逻辑说明:
- $this->input —— 获取请求参数中的某个值
- $this->push —— 将某个值添加到请求的参数中。
检查请求参数中是否存在 order ,如果不存在则添加该参数,值为 default 。
最新评论
站长大王来回复你了,长点心吧!