# laravel filter設計
https://learnku.com/articles/29100#545579
https://segmentfault.com/a/1190000018654280
(先看這篇 再往下看 這篇超重要)
## 講一下 newQuery()
newQuery () 是 model 的继承的 Database/Eloquent/Model
## 範例
假设我们有一个图书的列表,想要进行筛选:
标题含有 "我们" 的
定价大于 30 元的
出版社是 "大地出版社" 的
按照 ID 进行倒序排列
基础的 QueryFilter,然后我们所有的 Filter 都继承这个类
基本都是abstract class
```
abstract class QueryFilter
{
protected $request;
protected $builder;
public function __construct(Request $request)
{
$this->request = $request;
}
public function apply(Builder $builder)
{
$this->builder = $builder;
foreach ($this->filters() as $name => $value) {
if (method_exists($this, $name)) {
call_user_func_array([$this, $name], array_filter([$value]));
}
}
return $this->builder;
}
public function filters()
{
return $this->request->all();
}
}
```
**BookFilter**
```
class BookFilter extends QueryFilter
{
public function title($title)
{
return $this->builder->where('title', 'like', "%{$title}%");
}
public function price($price)
{
return $this->builder->where('price', '>=', "%{$price}%");
}
public function publisher($publisher)
{
return $this->builder->where('publisher', $publisher);
}
}
```
在上面的代码中,我们可以通过 URL 的参数来进行动态查询。
books?title=我们 // 查找标题含有我们的图书
books?title=我们&price=25 // 查找标题含有我们并且价格大于25元的图书
**当然,如果我们只进行到这一步是没法进行查询的,因为我们还没有地方调用 QueryFilter 中的 apply 方法。有一个绝佳的地方可以进行调用,那就是模型中的 scope**。
**注意:scopeFilter($query, QueryFilter $filters) 传参是抽象类,并使用该类调用了方法,所以实际使用时要传递实例化的继承类。**
```
class Book extends Model
{
public function scopeFilter($query, QueryFilter $filters)
{
return $filters->apply($query);
}
}
```
controller
```
public function index(BookFilter $filters)
{
return Book::filter($filters)->get();
}
```
## 分頁面
```
public function getModels($columns = ['*'], $request = null, $paginate = null, $with = null)
{
$query = $this->makeModelsQuery($request);
return $this->getModelsByQuery($query, $columns, $paginate, $with);
}
```
第二個的
```
/**
* Get result model by query builder and with relations and paginate.
*
* @param Builder $query
* @param array $columns
* @param int|null $x
* @param mixed|null $with
*/
public function getModelsByQuery($query, $columns = ['*'], $paginate = null, $with = null)
{
if ($with) {
$query = $query->with($with);
}
if ($paginate) {
return $query->paginate((int)$paginate, $columns);
}
return $query->get($columns);
}
```
###### tags: `Laravel`