Laravel多对多关联场景下如何按角色关联过滤搜索结果?
问题原因
你的搜索逻辑失效是SQL逻辑运算符优先级导致的:Laravel原始查询生成的SQL中,whereHas的角色过滤条件和第一个字段匹配条件是AND关系,但后续的orWhere会打破逻辑限制,最终查询条件等价于「(角色为Teacher且姓名匹配) 或 工号匹配 或 用户名匹配」,所以非对应角色的用户只要满足任意一个字段匹配就会被返回。
解决方案
把所有模糊搜索条件放到分组闭包中,保证角色过滤条件和所有搜索条件整体是AND关系,修改后的代码如下:
教师搜索方法修改
public function searchTeacher(Request $request) { $user = Auth::user(); // 用于头像展示 // 获取搜索关键词 $keyword = $request->table_search; $search = User::whereHas('roles', function($q){ $q->where('name', 'Teacher'); })->where(function ($query) use ($keyword) { // 所有模糊搜索条件放到闭包内做逻辑分组 $query->where('name','like',"%".$keyword."%") ->orWhere('nip','like',"%".$keyword."%") ->orWhere('username','like',"%".$keyword."%"); })->get(); return view('pages.admin.user.teacher.showTeacherFiltered', compact('search', 'user') ); }
学生搜索方法修改
public function searchStudent(Request $request) { $user = Auth::user(); // 用于头像展示 // 获取搜索关键词 $keyword = $request->table_search; $search = User::whereHas('roles', function($q){ $q->where('name', 'Student'); })->where(function ($query) use ($keyword) { // 所有模糊搜索条件放到闭包内做逻辑分组 $query->where('name','like',"%".$keyword."%") ->orWhere('nisn','like',"%".$keyword."%") ->orWhere('username','like',"%".$keyword."%"); })->get(); return view('pages.admin.user.student.showStudentFiltered', compact('search', 'user') ); }
逻辑说明
修改后生成的SQL查询条件等价于WHERE 角色为指定角色 AND (姓名匹配 或 编号匹配 或 用户名匹配),会先过滤出对应角色的用户,再在该范围内做模糊搜索,完全符合需求。
内容的提问来源于stack exchange,提问作者TheBetweener
相关产品推荐
相关产品推荐

