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

如何在Join查询中使用Eloquent的With关联查询?

问题分析与解决方案

错误原因

你在join()的闭包中调用了with()方法,而with()是Eloquent查询构建器(Illuminate\Database\Eloquent\Builder)的专属方法,并非JoinClause实例的方法,这直接导致了"Call to undefined method"错误。

修正方案

方案一:通过主查询链加载关联关系

前提是ManualTicketLog模型已定义与ManualTicket的关联:

  1. 在ManualTicketLog模型中添加关联:
// app/Models/ManualTicketLog.php
public function manualTicket()
{
    return $this->belongsTo(ManualTicket::class, 'manual_ticket_id');
}
  1. 修改查询代码,将with()移到主查询链上,指定加载manualTicket的prior_rerouted_ticket关联:
$manual_tickets = ManualTicketLog::select('*')
    ->where('manual_ticket_logs.user_id', '=', $user->id)
    ->where(function ($checkStatus) {
        $checkStatus->where('manual_ticket_logs.status', '=', 'Created')
            ->orWhere('manual_ticket_logs.status', '=', 'Started');
    })
    ->whereIn('manual_ticket_logs.id', function($q){
        $q->select(DB::raw('MAX(id) FROM manual_ticket_logs WHERE (manual_ticket_logs.status != "ClockedOutUser" and manual_ticket_logs.status != "ClockedOutSupervisor" and manual_ticket_logs.status != "AssignByLocation" and manual_ticket_logs.status != "Queued") GROUP BY manual_ticket_logs.manual_ticket_id'));  
    })
    ->join('manual_tickets', function ($join) {
        $join->on('manual_ticket_logs.manual_ticket_id', '=', 'manual_tickets.id')
            ->where('manual_tickets.hidden', '=', null);
        // 移除此处的with()调用
    })
    ->select('manual_tickets.*', 'manual_ticket_logs.id as manual_ticket_logs_id')
    ->with(['manualTicket.prior_rerouted_ticket']) // 在此处加载关联关系
    ->get();

方案二:切换查询主体为ManualTicket(更符合Eloquent设计)

如果你的核心目标是获取ManualTicket数据,直接从ManualTicket模型发起查询逻辑更清晰:

  1. 在ManualTicket模型中添加关联:
// app/Models/ManualTicket.php
public function logs()
{
    return $this->hasMany(ManualTicketLog::class, 'manual_ticket_id');
}
  1. 重构查询代码:
$manual_tickets = ManualTicket::where('hidden', '=', null)
    ->whereHas('logs', function ($logQuery) use ($user) {
        $logQuery->where('user_id', '=', $user->id)
            ->where(function ($checkStatus) {
                $checkStatus->where('status', '=', 'Created')
                    ->orWhere('status', '=', 'Started');
            })
            ->whereIn('id', function($q){
                $q->select(DB::raw('MAX(id) FROM manual_ticket_logs WHERE (status != "ClockedOutUser" and status != "ClockedOutSupervisor" and status != "AssignByLocation" and status != "Queued") GROUP BY manual_ticket_id'));  
            });
    })
    ->with('prior_rerouted_ticket') // 直接加载当前模型的关联
    ->join('manual_ticket_logs', function ($join) use ($user) {
        $join->on('manual_tickets.id', '=', 'manual_ticket_logs.manual_ticket_id')
            ->where('manual_ticket_logs.user_id', '=', $user->id)
            ->where(function ($checkStatus) {
                $checkStatus->where('status', '=', 'Created')
                    ->orWhere('status', '=', 'Started');
            })
            ->whereIn('manual_ticket_logs.id', function($q){
                $q->select(DB::raw('MAX(id) FROM manual_ticket_logs WHERE (status != "ClockedOutUser" and status != "ClockedOutSupervisor" and status != "AssignByLocation" and status != "Queued") GROUP BY manual_ticket_id'));  
            });
    })
    ->select('manual_tickets.*', 'manual_ticket_logs.id as manual_ticket_logs_id')
    ->get();

核心逻辑说明

with()的作用是预加载Eloquent模型的关联关系,它只能作用于Eloquent查询构建器实例,不能在处理SQL JOIN子句的JoinClause闭包中使用。必须将其放在主查询链上,明确指向需要加载的模型关联路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 00:01:15