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

同时拥有admin与support角色时无法查询数据行的问题解决

Laravel查询构建器多角色权限逻辑修正

问题场景

现有Laravel查询构建器代码如下,用于根据用户角色过滤runs数据:

return $builder
            ->when($authUser->hasRole('admin'), function (Builder $q) use ($authUser) {
                $q->whereHas('users', function (Builder $builder) use ($authUser) {
                    $builder->where('users.id', $authUser->id);
                });
            })
            ->when($authUser->hasRole('support'), function (Builder $q) {
                $q->whereHas('users', function (Builder $q2) {
                    $q2->where('support_access', true);
                });
            })
            ->when($authUser->hasRole('owner'), function (Builder $q) use ($authUser) {
                $q
                    ->where(function (Builder $builder) use ($authUser) {
                        $builder
                            ->whereIn('device_id', $authUser->company->devices->pluck('id'))
                            ->orWhereIn('id', $authUser->runs()->pluck('runs.id'));
                    });
            })
            ->when($authUser->hasRole('viewer'), function (Builder $q) use ($authUser) {
                $q->whereIn('id', $authUser->runs->pluck('id'));
            });

预期逻辑:

  • 用户仅拥有admin角色时,获取关联自己的runs数据
  • 用户仅拥有support角色时,获取所有support_access=true的runs数据
  • 用户同时拥有admin和support角色时,优先获取support_access=true的runs数据
  • 其他角色逻辑保持不变

当前问题:单独拥有admin或support角色时逻辑正常,但同时拥有两个角色时返回空数据。

问题原因

当用户同时拥有admin和support角色时,两个when条件都会触发,查询会同时添加两个且关系的过滤条件:

  1. runs必须关联当前用户(admin逻辑)
  2. runs必须关联support_access=true的用户(support逻辑)
    两种条件叠加后没有符合要求的数据,因此返回空结果。

解决方案

调整admin角色的when触发条件,仅当用户是admin且不具备support角色时,才执行admin对应的过滤逻辑。修改后的代码如下:

return $builder
            // 仅当用户是admin且无support角色时,执行admin专属过滤
            ->when($authUser->hasRole('admin') && !$authUser->hasRole('support'), function (Builder $q) use ($authUser) {
                $q->whereHas('users', function (Builder $builder) use ($authUser) {
                    $builder->where('users.id', $authUser->id);
                });
            })
            // 只要用户有support角色,就执行support逻辑
            ->when($authUser->hasRole('support'), function (Builder $q) {
                $q->whereHas('users', function (Builder $q2) {
                    $q2->where('support_access', true);
                });
            })
            ->when($authUser->hasRole('owner'), function (Builder $q) use ($authUser) {
                $q
                    ->where(function (Builder $builder) use ($authUser) {
                        $builder
                            ->whereIn('device_id', $authUser->company->devices->pluck('id'))
                            ->orWhereIn('id', $authUser->runs()->pluck('runs.id'));
                    });
            })
            ->when($authUser->hasRole('viewer'), function (Builder $q) use ($authUser) {
                $q->whereIn('id', $authUser->runs->pluck('id'));
            });

逻辑说明

  • 当用户同时拥有admin和support角色时,admin的when条件不满足(!$authUser->hasRole('support')为false),仅执行support的过滤逻辑,返回所有support_access=true的runs数据
  • 当用户仅拥有admin角色时,admin的when条件满足,执行原有的关联用户过滤逻辑
  • 其他角色的逻辑保持不变,不受影响

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:05:47