场景
在项目中 经常会面对一些条件的查询,这些查询条件好些是相同的。scope可以实现这些相同条件的复用.
局部作用域
这种用法是最常见的场景. eg: 一个论坛的问题的发布系统肯定是有一项是隐藏帖子,不显示给其他人看.
写法
1. 命名方式
. scope+自定义的方法名
2. 传参
. 第一个参数是查询生成器
. 如果传入参数 那么可以生成动态的效果 eg: scopePublished($query, $is_hidden)
3. 返回值也是固定的
. 需要返回查询生成器
4. 位置
. 在需要的Model中
5. 使用方法
. Question::published()->orderBy('updated_at', 'desc')->with('user')->get();
. Model直接调用
. 调用的时候方法小写且不写scope
/**
* 隐藏的帖子不显示
* @param $query
* @return mixed
*/
public function scopePublished($query)
{
return $query->where('is_hidden','F');
}
参考文档
https://laravel-china.org/docs/laravel/5.5/eloquent
全局作用域
1. 和局部作用域的显示调用不同,它是自动调用的。
2. 本质就是实现了Illuminate\Database\Eloquent\Scope apply 方法
3. 用法
. 在需要的Model boot 添加自定义的scope static::addGlobalScope(new AgeScope);
下面这部分摘抄自文档
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class AgeScope implements Scope
{
/**
* 将范围应用于给定的 Eloquent 查询生成器
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
return $builder->where('age', '>', 200);
}
}
<?php
namespace App;
use App\Scopes\AgeScope;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* 模型的「启动」方法
*
* @return void
*/
protected static function boot()
{
parent::boot();
static::addGlobalScope(new AgeScope);
}
}