Laravel Ticket模型查询范围:筛选未读回复超2条的工单
解决Laravel中筛选关联模型满足数量条件的工单问题
方法1:使用has方法直接筛选
Laravel的has方法支持通过闭包过滤关联模型,同时指定数量条件。直接在has的参数中传入比较运算符、目标数量和过滤关联模型的闭包即可:
public function scopeEscalatedTickets(Builder $query): Builder { return $query->has('replies', '>', 2, function (Builder $q) { $q->whereNot('status', Status::READ); }); }
该方法会生成EXISTS子查询,仅统计符合状态条件的回复数量,最终筛选出未读回复超过2条的工单。
方法2:使用withCount带条件+having
如果需要同时获取未读回复的具体数量,可以给withCount的关联添加闭包条件并指定别名,再通过having筛选目标数量:
public function scopeEscalatedTickets(Builder $query): Builder { return $query->withCount([ 'replies as unread_replies_count' => function (Builder $q) { $q->whereNot('status', Status::READ); } ])->having('unread_replies_count', '>', 2); }
你之前的写法无效是因为withCount('replies')未添加状态过滤,统计的是所有回复的数量而非仅未读回复。通过给withCount传入带闭包的关联数组,就能生成带条件的计数字段,再用having过滤即可。
方法3:使用whereHas简化写法
whereHas同样支持指定数量条件,写法更简洁,效果和方法1一致:
public function scopeEscalatedTickets(Builder $query): Builder { return $query->whereHas('replies', function (Builder $q) { $q->whereNot('status', Status::READ); }, '>', 2); }
内容的提问来源于stack exchange,提问作者SPQRInc
相关产品推荐
相关产品推荐

