Laravel与Vue项目报错Trying to get property 'total' of non-object如何解决?
错误原因
- 关联定义错误:你当前
Project模型中的latesReport方法仅返回查询构造器,未获取实际报告实例,且存在拼写错误(少字母t),调用时的latestReport和定义的方法名不匹配。 - 空值未处理:当项目没有关联报告时,获取到的最新报告为
null,直接访问total属性就会触发「非对象属性访问」报错。 - 性能问题:未使用预加载的情况下,循环访问关联会产生N+1查询,数据量大时性能很差。
解决步骤
第一步:修正Project模型的最新报告关联
用Laravel官方提供的latestOfMany一对一关联,专门用于获取一对多关联下的最新单条记录,代码如下:
// app/Models/Project.php public function latestReport() { // 需提前定义好Project和Report的hasMany关联 return $this->hasOne(Report::class)->latestOfMany(); }
第二步:修正User模型的total方法,添加空值处理
用null安全运算符或者optional函数处理无报告的场景,同时加预加载优化性能:
// app/Models/User.php public function total() { // 预加载关联避免N+1查询 return $this->project()->with('latestReport')->get()->sum(function ($project) { // 无报告时返回0,不参与求和 return $project->latestReport?->total ?? 0; }); }
如果你的PHP版本低于8.0,不支持null安全运算符,换成下面的写法即可:
return optional($project->latestReport)->total ?? 0;
高性能优化方案(可选)
如果项目数据量较大,你可以直接在数据库层面完成聚合计算,不需要查询出所有项目和报告实例,性能提升明显:
public function total() { return Report::whereIn('project_id', $this->project()->select('id')) // 只取每个项目的最新一条报告 ->whereRaw('id IN (SELECT MAX(id) FROM reports GROUP BY project_id)') ->sum('total'); }
内容的提问来源于stack exchange,提问作者Mary Tan
相关产品推荐
相关产品推荐

