如何在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表
| id | name |
|---|---|
| 1 | task1 |
| 2 | task2 |
| 3 | task3 |
task_role表
| task_id | role_id |
|---|---|
| 1 | 1 |
| 2 | 3 |
| 3 | 1 |
Schedule表
| id | name | task_id |
|---|---|---|
| 1 | schedule1 | 1 |
| 2 | schedule2 | 1 |
| 3 | schedule3 | 5 |
Spatie model_has_roles表
| role_id | model_type | model_id |
|---|---|---|
| 1 | App\Models\User | 2 |
| 2 | App\Models\User | 1 |
| 3 | App\Models\User | 5 |
当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
相关产品推荐
相关产品推荐

