You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Eloquent复杂嵌套关联查询逻辑错误排查与优化

修正Laravel Eloquent跨层级或条件查询问题

问题根源

你之前的代码存在两个核心问题:

  1. 字段归属错误:将CourseEnrollment的privileges字段放到了关联模型Member的查询闭包里,导致实际查询的是members.privileges而非course_enrollments.privileges
  2. 逻辑结构混乱:whereHas内部的orWhere没有和邮箱过滤条件正确嵌套,使得邮箱过滤规则被or逻辑覆盖,出现不符合过滤要求的结果

修正后的代码

CourseEnrollment::whereIn('domain_id', $domain_ids)
    ->where(function ($query) use ($filterUser) {
        // 条件1:当前课程报名记录的privileges不等于0
        $query->where('privileges', '!=', 0)
        // 条件2:关联的会员是导师,且符合邮箱过滤规则
        ->orWhereHas('member', function ($memberQuery) use ($filterUser) {
            $memberQuery->where('is_mentor', 1);
            
            if ($filterUser === 'true') {
                $memberQuery->where('email', 'NOT LIKE', '%@gmail.com%')
                            ->where('email', 'NOT LIKE', '%@yahoo.com%')
                            ->where('email', 'NOT LIKE', '%@boss.com%')
                            ->where('email', 'NOT LIKE', '%@test.com%');
            }
        });
    })
    ->get();

代码逻辑说明

  1. 外层where()包裹核心或逻辑:确保domain_id过滤是全局生效的,同时将两个核心条件(自身privileges≠0、关联会员符合要求)用or连接
  2. 条件1直接查询自身字段:直接针对CourseEnrollment的privileges字段做判断
  3. 条件2用orWhereHas()关联会员模型:
    • 先指定会员必须是导师(is_mentor=1)
    • 当开启邮箱过滤时,添加多个NOT LIKE规则,确保邮箱不在指定域名列表中
    • 所有会员相关的过滤规则都嵌套在orWhereHas的闭包里,只会作用于这个分支,不会干扰其他条件

可选优化:邮箱过滤的子查询写法

如果数据量较大,用子查询可以减少重复的NOT LIKE语句,提升查询效率:

if ($filterUser === 'true') {
    $memberQuery->whereNotIn('email', function ($subQuery) {
        $subQuery->select('email')
                 ->from('members')
                 ->where(function ($q) {
                     $q->where('email', 'LIKE', '%@gmail.com%')
                       ->orWhere('email', 'LIKE', '%@yahoo.com%')
                       ->orWhere('email', 'LIKE', '%@boss.com%')
                       ->orWhere('email', 'LIKE', '%@test.com%');
                 });
    });
}

内容的提问来源于stack exchange,提问作者Steinie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 17:54:32