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

Laravel Eloquent join多表后如何在select中包含with关联返回字段

Laravel Eloquent关联查询问题解决方案

1 join+select场景预加载关联结果的问题

错误原因

with()预加载是独立于主查询的二次查询机制,执行逻辑是先跑完主表查询拿到结果集,再根据主表结果的外键值查关联表,最后把关联数据挂载到对应主表模型的属性上,根本不需要在主查询的select中声明关联字段。你之前报错是因为把关联关系名manual_ticket_log当成了manual_tickets表的真实字段。

修复方案

只需要保证主查询select中保留manual_tickets.id(也就是manual_ticket_log关联用的外键对应的主表主键),删除select里错误声明的manual_tickets.manual_ticket_log as manual_ticket_log_id即可,预加载的manual_ticket_log会自动作为模型属性存在。
修复后的代码:

$display_tickets = ManualTicket::select(
        'u.name as name', 
        'i.name as initiator', 
        'manual_tickets.status as status', 
        'manual_tickets.description as description', 
        'manual_tickets.location as location', 
        'manual_tickets.created_at as created_at', 
        'manual_tickets.initiator_id as initiator_id', 
        'manual_tickets.id as manual_ticket_id'
    )
    ->leftJoin('users as u', 'u.id', '=', 'manual_tickets.user_id')
    ->leftJoin('users as i', 'i.id', '=', 'manual_tickets.initiator_id')
    ->where(function ($checkClients) use($target_client_id){
        $checkClients->where('u.client_id', '=', $target_client_id)
            ->orWhere('i.client_id', '=', $target_client_id);
    })
    ->whereBetween('manual_tickets.created_at', [$start_date->toDateString(), $end_date->addDays(1)->toDateString()])
    ->with('manual_ticket_log')
    ->orderBy("created_at", "DESC")
    ->get();

查询结果中每个ManualTicket实例都会自动携带manual_ticket_log属性,你可以直接通过$ticket->manual_ticket_log访问关联数据。


2 whereHas段报错strtolower() expects parameter 1 to be string, object given问题

错误原因

orWhere()方法的第一个参数需要传入字段名字符串或者闭包,你在代码中直接把$checkClients->whereHas(...)返回的查询构造器对象作为参数传给了orWhere(),导致参数类型不符合要求报错。

修复方案

直接链式调用orWhereHas()即可,不需要额外套orWhere()包裹。
修复后的代码:

$display_tickets = ManualTicket::select('*')
    ->with('user', 'initiator', 'manual_ticket_log')
    ->where(function ($checkClients) use($target_client_id){
        $checkClients->whereHas('user', function ($checkClient) use($target_client_id){
                $checkClient->where('client_id', '=', $target_client_id);
            })
            ->orWhereHas('initiator', function ($checkClient2) use($target_client_id){
                $checkClient2->where('client_id', '=', $target_client_id);
            });
    })
    ->whereBetween('manual_tickets.created_at', [$start_date->toDateString(), $end_date->addDays(1)->toDateString()])
    ->orderBy("created_at", "DESC")
    ->get();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 09:24:04