You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,后续扩展其他人员类型也可以直接复用:

  1. 先创建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;
        });
    }
}
  1. 在对应模型中引用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 03:54:03