Laravel中如何筛选与当前认证用户无工单关联的用户?
获取与当前用户无工单往来的用户列表解决方案
核心逻辑梳理
你要找的是和当前认证用户完全没有任何工单交互的用户——也就是既没有给当前用户发过工单,也没收到过当前用户工单的人。
原代码的问题
- 用
whereHas('tickets')方向错误:这个方法是筛选存在关联工单的用户,和你的需求完全相反。 - 闭包内写
count() == 0无效:whereHas的闭包是用来构建SQL查询条件的,不能直接返回布尔判断结果。
方案一:用whereNotExists直接查询(无需修改模型)
这种方式不需要改动User模型,直接通过子查询过滤符合条件的用户:
$currentUserId = auth()->user()->id; $users = User::where('id', '!=', $currentUserId) // 排除当前用户自己 ->whereNotExists(function ($query) use ($currentUserId) { $query->select(DB::raw(1)) ->from('tickets') ->where(function ($q) use ($currentUserId) { // 匹配两种有往来的情况,排除这些用户 // 1. 当前用户给对方发过工单 $q->where(function ($sub) use ($currentUserId) { $sub->where('user_id', $currentUserId) ->whereColumn('to_id', 'users.id'); }) // 2. 对方给当前用户发过工单 ->orWhere(function ($sub) use ($currentUserId) { $sub->where('to_id', $currentUserId) ->whereColumn('user_id', 'users.id'); }); }); }) ->get();
方案二:新增模型关联,用whereDoesntHave简化查询
先在User模型里新增一个「发送的工单」关联:
// User.php public function sentTickets() { return $this->hasMany(Ticket::class, 'user_id'); } // 保留原有的「接收的工单」关联 public function tickets() { return $this->hasMany(Ticket::class, 'to_id'); }
然后通过whereDoesntHave分别过滤两种往来情况:
$currentUserId = auth()->user()->id; $users = User::where('id', '!=', $currentUserId) // 过滤:对方没收到过当前用户的工单 ->whereDoesntHave('tickets', function ($query) use ($currentUserId) { $query->where('user_id', $currentUserId); }) // 过滤:对方没给当前用户发过工单 ->whereDoesntHave('sentTickets', function ($query) use ($currentUserId) { $query->where('to_id', $currentUserId); }) ->get();
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

