Laravel如何加载嵌套关联?从Accommodation关联Room及价格历史
当然可行!Laravel嵌套预加载轻松实现你的需求
完全没问题,这正是Laravel的**嵌套预加载(Nested Eager Loading)**设计要解决的场景——你可以一次性从模型A出发,加载其关联的模型B,同时加载模型B关联的模型C,既避免了N+1查询问题,又能把所有关联数据完美整合到结果里。
先确认你的关联关系是正确的
你给出的模型关联代码完全符合逻辑:
Accommodation(A)hasManyAccommodationRoom(B)AccommodationRoom(B)hasManyRoomPricingHistory(C)- 反向关联也都配置正确,这是实现嵌套预加载的基础。
控制器中实现嵌套预加载的代码
在你的Accommodation控制器里,只需要用Laravel的with()方法,通过**点号.**来嵌套关联关系即可:
// 获取所有Accommodation,同时加载关联的AccommodationRoom,以及每个Room对应的RoomPricingHistory $accommodations = Accommodation::with('accommodationRoom.roomPricingHistory')->get();
如何访问整合后的关联数据
拿到结果后,你可以直接通过属性链式访问所有关联数据,比如遍历输出:
foreach ($accommodations as $accommodation) { echo "住宿:" . $accommodation->name . "<br>"; // 遍历当前住宿下的所有房间 foreach ($accommodation->accommodationRoom as $room) { echo "房间类型:" . $room->room_type . "<br>"; // 遍历当前房间下的所有价格历史 foreach ($room->roomPricingHistory as $priceRecord) { echo "价格:" . $priceRecord->price . " | 更新时间:" . $priceRecord->updated_at . "<br>"; } } }
进阶:筛选关联数据(可选)
如果需要对关联数据做筛选(比如只加载可用房间、只加载最近的价格记录),可以用闭包来定制预加载逻辑:
$accommodations = Accommodation::with([ // 筛选出可用的房间 'accommodationRoom' => function ($query) { $query->where('is_available', true); }, // 筛选出最近30天的价格记录,并按时间倒序 'accommodationRoom.roomPricingHistory' => function ($query) { $query->where('created_at', '>=', now()->subDays(30)) ->orderBy('created_at', 'desc'); } ])->get();
内容的提问来源于stack exchange,提问作者Farshad
相关产品推荐
相关产品推荐

