Laravle 模型全局作用域
就是给每次的查询获取sql,添加固定的过滤条件。主要,需要给添加的字段添加表前缀。使用模型的公有方法getTable方法获取表名
1. 定义全局作用域
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class FilterDeleteScope extends Scope
{
public function apply(Builder $builder, Model $model)
{
// 使用$model->getTable()获取表名
$builder->where($model->getTable().'.is_delete', '=', 1);
}
}
2. 注册全局作用域
尽量让某些固有的表字段名称统一,比如是否删除的字段,等。这样就可以使用统一的方式处理。
比如1中提到的对is_delete字段定义了模型全局作用域,假设is_delete每张表都有的话,那么我们可以再次重写模型类。让表的模型继承重写的基类
/**
* 重写模型基类
*/
use Illuminate\Database\Eloquent\Model;
// 根据具体的空间作用域引入FilterDeleteScope
use FilterDeleteScop;
class BaseModel extends Model
{
protected static function booted()
{
// 调用父类的方法
parent::booted();
// 添加全局作用域
static::addGlobalScope(new FilterDeleteScope);
// ... 其他的全局作用域
}
}
class User extends BaseModel
{
// 这样使用,User模型查询时,就自带过滤is_delete条件了
}
3. 查询时取消全局作用域
-
取消所有的全局作用域
$userBuilder = User::withoutGlobalScopes(); // 然后使用$userBilder进行下面的查询逻辑,当然也可以在一行写完所有的
-
取消部分全局作用域
$userBuilder = User::withoutGlobalScopes([FilterDeleteScpoe::class, ...]); // 然后使用$userBilder进行下面的查询逻辑,当然也可以在一行写完所有的 // 如果只取消一个的话,则不需要[]
4. 其他
其他的方式参考官方文档即可,比如闭包的方式,动态方式等