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
相关产品推荐
相关产品推荐

