关联预加载怎么避免加载关联的关联?

谢谢 @zxdstyle@leo 两位老师的指导和提示,我意识到问题所在了,是因为我在apartment中设置了追加到模型的beds_count属性,用来统计床位数量,在对应的函数中我调用了apartment->rooms,关闭这个追加的beds_count后即可正常显示。
至于beds_count的更好的解决办法是通过设置apartment与bed模型的远程一对多关联,然后withCount即可。

Laravel版本:6.0
我在使用模型关联查询的预加载时,发现with会预加载关联的关联,具体请看描述:

class Apartment extends Model
{
    public function rooms()
    {
        return $this->hasMany('App\Models\Room');
    }
}
class Room extends Model
{
    public function Apartment()
    {
        return $this->belongsTo('App\Models\Apartment');
    }
}

我现在通过ajax查询想要返回符合条件的room列表同时包含room所属的apartment的title属性。

我尝试的代码:

$rooms = $room->with('apartment:id,title')
    ->orderBy($sortName,$sortOrder)
    ->offset($offset)
    ->limit($limit)
    ->get();
return $rooms;

现在的问题是这样返回的room列表中,包含了room的关联apartment的关联:roomsroom->apartment->rooms,这样数据量大的情况下,查询的非常慢。
我想请问一下,要怎么才能在room列表中只包含room->apartment->title呢?

即便我取消了通过with关联预加载,采用foreach循环方式获取room->apartment->title,返回的rooms列表中仍然包含room->apartment->rooms!

附上Room::with(‘apartment’)与Room::with(‘apartment:id,name’)这两种方式的返回值截图:


可以看到不论设置不设置with的字段限制,都会返回apartment->rooms,这么一大堆没用的东西。

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
最佳答案

正常情况下Laravel是不会自己预加载关联的,你可以从以下几点排查:

  1. 检查一下你的 Apartment 模型有没有定义默认预加载,类似以下写法:
    protected $with = ['rooms'];
  2. 检查一下有没有主动调用 rooms 关联,类似一下写法:
    foreach($rooms as $room) {
        $room->apartment->rooms
    }
4年前 评论
nidongde (楼主) 4年前
nidongde (楼主) 4年前
讨论数量: 2

正常情况下Laravel是不会自己预加载关联的,你可以从以下几点排查:

  1. 检查一下你的 Apartment 模型有没有定义默认预加载,类似以下写法:
    protected $with = ['rooms'];
  2. 检查一下有没有主动调用 rooms 关联,类似一下写法:
    foreach($rooms as $room) {
        $room->apartment->rooms
    }
4年前 评论
nidongde (楼主) 4年前
nidongde (楼主) 4年前
leo

贴出完整的 Apartment 定义

4年前 评论
nidongde (楼主) 4年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!