Global Scopes

广告位

有时您可能希望定义一个 scope 可以用于模型的所有查询中。本质上,这也是 Eloquent 的&#8221…

有时您可能希望定义一个 scope 可以用于模型的所有查询中。本质上,这也是 Eloquent 的”软删除”功能的实现原理。Global scopes 是通过 PHP traits 的组合以及实现 IlluminateDatabaseEloquentScopeInterface 接口来定义的。

首先,我们需要定义一个 trait。 这里我们用 Laravel 的 SoftDeletes 举例:

trait SoftDeletes {     /**      * Boot the soft deleting trait for a model.      *      * @return void      */     public static function bootSoftDeletes()     {         static::addGlobalScope(new SoftDeletingScope);     } }

如果一个 Eloquent 模型引入了一个 trait ,而这个 trait 中带有符合 bootNameOfTrait 惯例命名的方法 ,那么这个方法会在 Eloquent 模型启动的时候调用, 您可以在此时注册 global scope ,或者做一些其他您想要的操作。定义的 scope 必须实现 ScopeInterface 接口,这个接口提供了两个方法:apply 和 remove。

apply 方法接受一个 IlluminateDatabaseEloquentBuilder 查询构造器对象以及它所应用的 Model,用来添加这个 scope 所需的额外的 where 子句。而remove 方法同样接受一个 Builder 对象以及 Model ,用来反向的执行 apply 操作。也就是说,remove 方法应该移除已经添加的 where 子句 (或者其他查询子句)。因此,我们的 SoftDeletingScope 的方法应该如下:

/**  * Apply the scope to a given Eloquent query builder.  *  * @param  IlluminateDatabaseEloquentBuilder  $builder  * @param  IlluminateDatabaseEloquentModel  $model  * @return void  */ public function apply(Builder $builder, Model $model) {     $builder->whereNull($model->getQualifiedDeletedAtColumn());      $this->extend($builder); }  /**  * Remove the scope from the given Eloquent query builder.  *  * @param  IlluminateDatabaseEloquentBuilder  $builder  * @param  IlluminateDatabaseEloquentModel  $model  * @return void  */ public function remove(Builder $builder, Model $model) {     $column = $model->getQualifiedDeletedAtColumn();      $query = $builder->getQuery();      foreach ((array) $query->wheres as $key => $where)     {         // If the where clause is a soft delete date constraint, we will remove it from         // the query and reset the keys on the wheres. This allows this developer to         // include deleted model in a relationship result set that is lazy loaded.         if ($this->isSoftDeleteConstraint($where, $column))         {             unset($query->wheres[$key]);              $query->wheres = array_values($query->wheres);         }     } }

关于作者: 华为工程师芊芊

为您推荐

广告位

发表评论