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

Laravel中when子句内使用wherePivot失效报错求助

问题原因

在when闭包内调用wherePivot时,Laravel无法正确关联到关联模型的中间表上下文,导致生成的SQL错误引用了不存在的pivot列;而直接在with的闭包中调用wherePivot时,关联查询的上下文完整,Laravel能自动替换为实际的中间表名称,因此可以正常执行。

解决方案

方案1:硬编码中间表名称(简单直接)

将when闭包里的wherePivot替换为where,明确指定中间表的实际名称和字段(中间表名称需根据你的数据库结构调整,比如company_subscriber):

return Company::where('owner_id', auth()->user()->id)
    ->with(['subscribers' => function ($q) {
            $q->wherePivot('is_customer', 1);
            $q->when($this->type != 'all', function ($q) {
                $q->where('company_subscriber.is_customer', 1);
            });
            $q->when($this->example != 'all', function ($q) {
                $q->where('example', 1);
            });
        }
    ])
    ->firstOrFail();

方案2:动态获取中间表名称(推荐,无需硬编码)

利用关联查询构建器的getTable()方法自动获取中间表名称,避免硬编码:

return Company::where('owner_id', auth()->user()->id)
    ->with(['subscribers' => function ($q) {
            $q->wherePivot('is_customer', 1);
            $q->when($this->type != 'all', function ($q) {
                $pivotTable = $q->getTable();
                $q->where("{$pivotTable}.is_customer", 1);
            });
            $q->when($this->example != 'all', function ($q) {
                $q->where('example', 1);
            });
        }
    ])
    ->firstOrFail();

方案3:用if判断替代when(场景适配)

如果逻辑简单,直接用原生if判断替代when,可以保留wherePivot的用法:

return Company::where('owner_id', auth()->user()->id)
    ->with(['subscribers' => function ($q) {
            $q->wherePivot('is_customer', 1);
            if ($this->type != 'all') {
                $q->wherePivot('is_customer', 1);
            }
            $q->when($this->example != 'all', function ($q) {
                $q->where('example', 1);
            });
        }
    ])
    ->firstOrFail();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:45:28