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

如何使用Eloquent排除user表中含指定角色的数据行

Eloquent查询排除role字段特定值的实现方案

下面是几种不同场景下的可用实现,你可以根据业务复用需求选择:

  • 单次查询临时过滤
    最直接的方式,只需要在构建查询时手动加条件即可,适合仅个别查询需要过滤的场景:
    单角色排除用where:
    // 排除role为banned的用户
    $users = User::where('role', '!=', 'banned')->get();
    
    多角色排除用whereNotIn:
    // 同时排除admin、guest两类角色
    $users = User::whereNotIn('role', ['admin', 'guest'])->get();
    
  • 本地作用域复用过滤逻辑
    如果这个过滤规则需要在多个查询里重复用,可以在User模型中定义本地查询作用域,避免重复写条件:
    先在app/Models/User.php里加对应scope方法:
    /**
     * 排除指定角色的查询作用域
     * @param mixed $query
     * @param array $excludedRoles 要排除的角色列表,默认排除封禁账号
     * @return mixed
     */
    public function scopeWithoutRoles($query, array $excludedRoles = ['banned'])
    {
        return $query->whereNotIn('role', $excludedRoles);
    }
    
    用的时候直接调用作用域即可,不传参默认排除封禁用户,传参可以自定义要排除的角色:
    // 默认排除banned角色
    $normalUsers = User::withoutRoles()->paginate(15);
    // 自定义排除admin、super_admin角色
    $frontUsers = User::withoutRoles(['admin', 'super_admin'])->get();
    
  • 全局作用域默认全局过滤
    如果业务要求所有查询User表的场景默认都要排除某类角色(比如所有前台、接口查询都不返回被封禁的用户),可以用全局作用域,一次配置之后所有查询默认带上过滤条件,不会因为漏写条件查出不符合要求的数据。
    直接在User模型的booted方法中注册全局作用域即可:
    protected static function booted()
    {
        // 注册全局作用域,默认所有查询排除banned角色
        static::addGlobalScope('exclude_banned_user', function ($query) {
            $query->where('role', '!=', 'banned');
        });
    }
    
    配置后常规查询默认自动过滤,如果遇到特殊场景(比如后台需要查看所有被封禁用户),可以临时移除全局作用域:
    // 移除指定全局作用域,查询包含被封禁用户在内的所有数据
    $allUsers = User::withoutGlobalScope('exclude_banned_user')->get();
    

注意:不要和模型的$hidden属性搞混,$hidden是序列化输出时隐藏指定字段,不会在SQL查询阶段过滤数据行,达不到排除整行数据的效果。

内容的提问来源于stack exchange,提问作者Zen3x

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 21:27:47