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

Laravel实例化Model后with()预加载无效的问题求助

问题根源

Laravel Eloquent的查询构建器是不可变对象,调用with这类方法时,它不会修改原有的query实例,而是返回一个全新的、包含预加载配置的查询构建器。你之前的写法只是调用了with但没接收返回值,后续的find/get还是用最初创建的、没有预加载的query,自然触发N+1查询。

修复方案

把with方法的返回值重新赋值给$query变量,让后续的查询操作使用这个带预加载配置的构建器。同时注意原代码里$modelName未正确引用,要改成$this->modelName(因为仓库类里定义的是类属性,Trait里通过$this访问)。

修改后的EloquentTrait代码:

public function findId($data)
{
    $query = new $this->modelName;
    // 关键:将with的返回值重新赋值给$query
    $query = $query->with($data['with']);
    $row = $query->find($data['id']);

    return $row;
}


public function getRows($data)
{
    $query = new $this->modelName;
    $query = $query->with($data['with']);
    if(!empty($data['where'])){
        foreach($data['where'] as $where){
            // 严谨起见,where也应该赋值(虽然之前能用,但遵循统一规范避免潜在问题)
            $query = $query->where($where['column'], $where['value']);
        }
    }
    $rows = $query->get();

    return $rows;
}
补充说明

所有Eloquent的链式查询方法(with、where、orderBy、limit等)都遵循这个不可变原则,必须通过赋值来保留修改后的查询状态,不然你的配置不会生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:24:57