Laravel 8.12:关联查询无法在子数组中获取Printer title字段
Laravel 8.12:无法在Orders子数组中获取Printer的Title字段
表结构
- Order表:id, name, printer_id, resource_id
- Printer表:id, title
- Resources表:id, name
当前代码
$resources = Resource::with('orders') ->leftJoin('orders', 'resources.id', '=', 'orders.resource_id') ->leftJoin('printers', 'orders.printer_id', '=', 'printers.id') ->select('resources.*') ->groupBy('resources.id');
当前输出结果
[ { "id": 2, "title": "user 2", "orders": [ { "id": 190, "resource_id": "2", "printer_id": 2 }, { "id": 193, "resource_id": "2", "printer_id": 3 }, ] }, { "id": 3, "title": "user 3", "orders": [ { "id": 207, "resource_id": "3", "printer_id": 3 } ] }, { "id": 4, "title": "user 4", "orders": [ { "id": 466, "resource_id": "4", "printer_id": 4 }, { "id": 370, "resource_id": "4", "printer_id": 5 } ] } ]
期望输出结果
[ { "id": 2, "orders": [ { "id": 190, "resource_id": "2", "title": "user 2", "printer_id": 2 }, { "id": 193, "resource_id": "2", "title": "user 3", "printer_id": 3 } ] }, { "id": 3, "orders": [ { "id": 207, "title": "user 3", "resource_id": "3", "printer_id": 3 } ] }, { "id": 4, "orders": [ { "id": 466, "title": "user 4", "resource_id": "4", "printer_id": 4 }, { "id": 370, "title": "user 5", "resource_id": "4", "printer_id": 5 } ] } ]
解决方案
问题根源
- 混用了Eloquent关联预加载(
with('orders'))和手动join,预加载的orders未关联printer数据; select('resources.*')仅查询了Resources表字段,未包含Printer的title;- 手动
join+groupBy的方式破坏了Eloquent关联逻辑,容易丢失关联数据。
正确实现方式
步骤1:完善模型关联
在Order模型中添加与Printer的关联:
// app/Models/Order.php public function printer() { return $this->belongsTo(Printer::class); }
在Resource模型中确保与Order的关联正确:
// app/Models/Resource.php public function orders() { return $this->hasMany(Order::class); }
步骤2:嵌套预加载关联数据
直接使用Eloquent嵌套预加载,无需手动join,代码更简洁且符合框架规范:
$resources = Resource::with('orders.printer')->get();
步骤3:调整输出格式(匹配期望结果)
如果需要将Printer的title直接放在orders数组同级,可通过with的闭包自定义查询字段:
$resources = Resource::with(['orders' => function ($query) { $query->select('orders.*', 'printers.title') ->leftJoin('printers', 'orders.printer_id', '=', 'printers.id'); }])->get();
为什么不推荐手动join?
手动join会将多表数据扁平化,当一个Resource对应多个Order时,会产生重复的Resource记录,必须用groupBy去重,既增加查询复杂度,又容易丢失关联数据。而Eloquent预加载机制会自动处理一对多关联,避免数据重复,同时保持结构清晰。
内容的提问来源于stack exchange,提问作者Murugadas
相关产品推荐
相关产品推荐

