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

Laravel使用Spatie时如何按角色分类分组显示权限列表

问题根源

当前使用左连接查询得到的是扁平化结构的结果集,每条权限记录都会携带对应分类的名称,遍历单条数据时每次都输出分类标题,自然会出现重复渲染分类名的问题。

修复步骤

1. 完善模型关联

在RoleCategory模型中定义和权限表的一对多关联:

// app/Models/RoleCategory.php
public function permissions()
{
    return $this->hasMany(\Spatie\Permission\Models\Permission::class, 'role_category_id');
}

2. 调整控制器查询逻辑

替换原来的左连接查询,改用Eloquent预加载关联的权限数据,同时修正原代码里的拼写错误(RoleCatgory拼写错误、Leftjoin写法不符合规范):

// 控制器方法内
$categories = RoleCategory::with('permissions')->get();
// 提前获取当前角色已有的权限ID数组,根据你实际的业务逻辑调整$role的获取方式
$rolePermissions = $role->permissions->pluck('id')->toArray();
return view('你的视图文件路径', compact('categories', 'rolePermissions'));

3. 重构Blade模板渲染逻辑

改用两层循环结构:外层遍历角色分类,仅输出一次分类标题;内层遍历当前分类下的所有权限,渲染复选框,从根源避免标题重复。同时修复原模板里复选框ID重复的bug:

@foreach($categories as $category)
  <h3>{{ $category->category_name }}</h3>
  <div class="row">
    @foreach($category->permissions as $permission)
      @php $checked = in_array($permission->id, $rolePermissions) ? 'checked' : '' @endphp
      <div class="col-md-4 mb-2">
        <input 
          type="checkbox" 
          class="form-check-input" 
          id="permission-{{ $permission->id }}" 
          name="permission[]" 
          {{ $checked }} 
          value="{{ $permission->id }}"
        >
        <label class="form-check-label" for="permission-{{ $permission->id }}">
          {{ $permission->name }}
        </label>
      </div>
    @endforeach
  </div>
@endforeach

额外说明:原模板中所有复选框和label的id/for属性都写死为exampleCheck,不符合HTML规范,会导致点击任意label都只能选中第一个复选框,上述代码已经改为用权限ID拼接唯一标识的写法,可直接使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:03:24