Laravel Eloquent:筛选用户关联模块的子模块问题求助
解决方案
要实现只返回用户有权限的子模块,你需要在预加载subModules时添加约束,筛选出与当前用户关联的子模块。以下是两种可行的实现方式:
方式一:在控制器中动态约束预加载
直接在查询时给子模块添加权限过滤逻辑,这种方式更灵活,避免在模型中硬编码用户上下文:
$user = auth()->user(); $modules = $user->modules() ->with(['subModules' => function ($query) use ($user) { // 筛选出当前用户有权限的子模块 $query->whereHas('users', function ($q) use ($user) { $q->where('user_id', $user->id); }); }]) ->get() ->toArray();
方式二:在模型中定义带权限的子模块关联
如果需要多处复用这个逻辑,可以在Module模型中新增一个关联方法,专门返回当前用户可访问的子模块:
修改Module模型
class Module extends Model { // ... 原有代码 // 新增:返回当前用户可访问的子模块 public function accessibleSubModules() { return $this->subModules()->whereHas('users', function ($query) { $query->where('user_id', auth()->id()); }); } }
修改User模型的modules关联
class User extends Authenticatable { // ... 原有代码 public function modules() { return $this->belongsToMany(Module::class, 'modules_users') ->where('group', null) ->with('accessibleSubModules'); // 替换原来的subModules } }
控制器中调用
auth()->user()->modules->toArray();
逻辑说明
- 原代码中
with('subModules')会加载父模块下的所有子模块,没有做权限过滤; - 使用
whereHas('users')可以关联多对多表modules_users,只保留与当前用户存在关联的子模块; - 两种方式都能实现需求,可根据业务场景选择:需要动态传用户时用方式一,复用逻辑时用方式二。
内容的提问来源于stack exchange,提问作者Elena Martín Castillo
相关产品推荐
相关产品推荐

