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

Laravel ACL系统使用Gate报错:Call to a member function getKey() on bool

Laravel Gate 报错:Call to a member function getKey() on bool

问题原因

这个错误是因为你在Gate回调中给hasRole方法传入了错误的参数类型,或者User模型的hasRole方法未正确处理集合类型参数,导致返回的布尔值被框架后续逻辑错误地调用了getKey()方法。

你的代码里$permission->roles是Eloquent集合(通过with('roles')预加载得到),但通常hasRole方法是用来检查用户是否拥有单个角色(传入角色名称、ID或单个模型),而非直接传入集合。

解决方案

1. 修正Gate回调的参数传递

将集合转换为角色名称/ID数组,适配hasRole方法的参数要求:

Gate::define($permission->name , function ($user) use($permission){
    // 传递角色名称数组给hasRole
    return $user->hasRole($permission->roles->pluck('name')->toArray());
});

如果你的hasRole方法支持通过ID检查,也可以用:

return $user->hasRole($permission->roles->pluck('id')->toArray());

如果hasRole仅支持单个角色检查,改用集合的some方法验证用户是否拥有任意关联角色:

Gate::define($permission->name , function ($user) use($permission){
    return $permission->roles->some(function ($role) use ($user) {
        return $user->hasRole($role);
    });
});

2. 优化getPermissions方法

get()已经返回Eloquent集合,无需调用all()转数组,简化代码:

protected function getPermissions(): \Illuminate\Database\Eloquent\Collection
{    
    return Permission::with('roles')->get();
}

3. 确保User模型的hasRole方法兼容多参数类型

如果是自定义的hasRole方法,建议完善逻辑以支持单个角色、数组、模型等多种参数类型:

public function hasRole($role)
{
    // 处理字符串类型(角色名称)
    if (is_string($role)) {
        return $this->roles->contains('name', $role);
    }

    // 处理数组类型(角色名称/ID数组)
    if (is_array($role)) {
        return $this->roles->pluck('name')->intersect($role)->isNotEmpty();
    }

    // 处理模型实例
    return $this->roles->contains($role);
}

验证

修改完成后,重新请求接口或页面,authorize('show-users')即可正常验证权限,不会再出现getKey()调用错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 01:52:35