如何让Laravel Eloquent全局应用类似软删除的自定义查询条件?
在Laravel Eloquent中实现类似软删除的
is_ready默认过滤逻辑 要实现和软删除一致的默认过滤逻辑,核心是利用Eloquent全局作用域,自动给所有模型查询追加is_ready = true的条件,同时提供方法灵活取消过滤或定向查询非ready记录。
方法一:独立全局作用域类(推荐,便于维护)
- 创建作用域类
在app/Scopes目录下新建ReadyScope.php(无Scopes目录则手动创建):
<?php namespace App\Scopes; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Scope; class ReadyScope implements Scope { public function apply(Builder $builder, Model $model) { // 默认仅查询is_ready为true的记录 $builder->where('is_ready', true); } }
- 在模型中注册作用域
打开目标模型(比如App\Models\Article),在boot方法中注册全局作用域,并添加自定义查询方法:
<?php namespace App\Models; use App\Scopes\ReadyScope; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; class Article extends Model { protected $fillable = ['title', 'content', 'is_ready']; protected static function boot() { parent::boot(); // 注册全局作用域 static::addGlobalScope(new ReadyScope); } // 查询所有记录(包含is_ready=false的) public function scopeWithUnready(Builder $builder) { return $builder->withoutGlobalScope(ReadyScope::class); } // 仅查询is_ready=false的记录 public function scopeOnlyUnready(Builder $builder) { return $builder->withoutGlobalScope(ReadyScope::class)->where('is_ready', false); } }
方法二:匿名全局作用域(快速实现)
若无需单独维护作用域类,可直接在模型内定义匿名全局作用域:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; class Article extends Model { protected $fillable = ['title', 'content', 'is_ready']; protected static function boot() { parent::boot(); static::addGlobalScope('ready', function (Builder $builder) { $builder->where('is_ready', true); }); } // 取消过滤,查询全部记录 public function scopeWithUnready(Builder $builder) { return $builder->withoutGlobalScope('ready'); } }
使用示例
- 默认查询(自动返回
is_ready=true的记录):
$readyArticles = Article::all();
- 查询所有记录(包含未ready的):
$allArticles = Article::withUnready()->get();
- 仅查询未ready的记录:
$unreadyArticles = Article::onlyUnready()->get();
内容的提问来源于stack exchange,提问作者Eric Brown
相关产品推荐
相关产品推荐

