Laravel 8中如何为继承Person类的模型设置全局查询过滤范围
实现方案
你要的效果可以通过 Laravel 提供的全局查询作用域实现,原理和SoftDeletes trait 完全一致,所有查询会自动附加你指定的过滤条件。
方案1:直接在模型中定义(简单场景够用)
直接在Client模型的启动方法中添加全局作用域,同时可以配套新增自动赋值逻辑,避免手动设置persontype_id:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Builder; class Client extends Person { protected static function booted() { // 所有查询自动附加客户类型过滤 static::addGlobalScope('client_filter', function (Builder $builder) { $builder->where('persontype_id', 1); }); // 新增数据时自动填充类型字段 static::creating(function ($model) { $model->persontype_id = 1; }); } }
同理给Employee模型做相同配置,把persontype_id的值改成对应员工的编号即可。配置完成后Client::all()就只会返回客户数据。
如果特殊场景需要绕过过滤查询所有数据,可以调用withoutGlobalScope方法:
// 临时取消过滤,查询people表所有数据 $allPerson = Client::withoutGlobalScope('client_filter')->get();
方案2:封装为Trait复用(类似SoftDeletes用法)
如果需要更规范的复用,可以和SoftDeletes一样把逻辑封装为独立的Trait,后续扩展其他人员类型也可以直接复用:
- 先创建Trait文件
app/Models/Traits/HasPersonTypeScope.php
<?php namespace App\Models\Traits; use Illuminate\Database\Eloquent\Builder; trait HasPersonTypeScope { public static function bootHasPersonTypeScope() { // 自动附加类型过滤 static::addGlobalScope('person_type_filter', function (Builder $builder) { $builder->where('persontype_id', static::$personTypeId); }); // 自动填充类型字段 static::creating(function ($model) { $model->persontype_id = static::$personTypeId; }); } }
- 在对应模型中引用Trait并配置类型值即可
// Client模型 class Client extends Person { use HasPersonTypeScope; protected static $personTypeId = 1; } // Employee模型 class Employee extends Person { use HasPersonTypeScope; protected static $personTypeId = 2; }
内容的提问来源于stack exchange,提问作者Tales
相关产品推荐
相关产品推荐

