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

如何在Laravel中通过Spatie Permission查询用户有权限的Schedule

问题:获取登录用户有权限的Task关联的Schedule

我有两张表:Schedules和Tasks,二者为一对一关联,模型代码如下:

class Schedule extends Model
{
    public function task() {
        return $this->belongsTo(Task::class, 'task_id');
    }
}

Task模型与Spatie的Role模型通过task_role中间表形成多对多关联,模型代码如下:

class Task extends Model
{
    public function roles() {
        return $this->belongsToMany(Role::class);
    }
}

请问如何编写查询语句,获取与登录用户有权限的Task相关联的所有Schedule?

示例数据

Tasks表

idname
1task1
2task2
3task3

task_role表

task_idrole_id
11
23
31

Schedule表

idnametask_id
1schedule11
2schedule21
3schedule35

Spatie model_has_roles表

role_idmodel_typemodel_id
1App\Models\User2
2App\Models\User1
3App\Models\User5

当user2登录时,仅能看到schedule1和schedule2。


解决方案

方式一:Eloquent嵌套关联查询

直接通过模型关联层层筛选,从Schedule出发匹配关联的Task,再匹配属于当前用户的Role:

use App\Models\Schedule;
use Illuminate\Support\Facades\Auth;

$user = Auth::user();

$schedules = Schedule::whereHas('task.roles', function ($query) use ($user) {
    $query->where('model_has_roles.model_id', $user->id)
          ->where('model_has_roles.model_type', get_class($user));
})->get();

说明

  • whereHas('task.roles') 仅保留关联了符合条件Task的Schedule,该Task需关联当前用户的角色
  • 闭包内直接对接Spatie的model_has_roles表,精准筛选用户所属角色

方式二:分步查询(直观逻辑)

先获取用户有权限的Task ID集合,再查询关联这些Task的Schedule:

use App\Models\Schedule;
use Illuminate\Support\Facades\Auth;

$user = Auth::user();
// 获取用户所有角色ID
$roleIds = $user->roles()->pluck('id');
// 获取这些角色关联的Task ID
$taskIds = \App\Models\Task::whereHas('roles', function ($query) use ($roleIds) {
    $query->whereIn('roles.id', $roleIds);
})->pluck('id');
// 查询关联目标Task的Schedule
$schedules = Schedule::whereIn('task_id', $taskIds)->get();

结果验证

对于user2(ID=2),其拥有角色ID=1,对应Task为ID=1和3,但Schedule中仅存在task_id=1的schedule1和schedule2,与预期一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:04:55