Laravel创建BankAccount时触发'Trying to get property 'user_id' of non-object'错误
问题分析与修复方案
这个问题的核心原因是Eloquent关联属性的缓存机制:当你首次调用$user->bankAccount时,它会返回null(因为当时没有关联记录),这个null会被缓存起来。而当你通过$user->bankAccount()->create(...)创建新记录后,$user->bankAccount并不会自动刷新,依然是缓存的null,这时候用它实例化BankAccountResource就会触发“Trying to get property 'user_id' of non-object”的错误。
修复方法(三种可选)
方法1:直接使用create()返回的实例
create()方法会返回刚创建的BankAccount模型对象,我们可以直接用这个对象来生成资源,完全避开缓存问题:
public function update(Request $request, User $user) { if (!$user->bankAccount) { // 保存创建的实例 $bankAccount = $user->bankAccount()->create($request->all()); } else { $user->bankAccount()->update($request->all()); // 更新后获取最新的实例(避免缓存旧数据) $bankAccount = $user->bankAccount->fresh(); } return new BankAccountResource($bankAccount); }
方法2:手动刷新关联缓存
创建完成后,调用load()方法重新加载bankAccount关联,覆盖之前的缓存值:
public function update(Request $request, User $user) { if (!$user->bankAccount) { $user->bankAccount()->create($request->all()); // 手动加载关联,刷新缓存 $user->load('bankAccount'); } else { $user->bankAccount()->update($request->all()); // 可选:更新后也刷新一下,确保拿到最新数据 $user->bankAccount->refresh(); } return new BankAccountResource($user->bankAccount); }
方法3:用updateOrCreate()简化代码(推荐)
Laravel提供了updateOrCreate()方法,可以一键实现“有则更新,无则创建”,并且会直接返回最新的模型实例,代码更简洁且避免缓存问题:
public function update(Request $request, User $user) { $bankAccount = $user->bankAccount()->updateOrCreate( ['user_id' => $user->id], // 查询条件(一对一关联的唯一标识) $request->all() // 要设置的属性 ); return new BankAccountResource($bankAccount); }
为什么更新操作正常?
更新时你是通过$user->bankAccount()->update(...)执行的,这时候$user->bankAccount已经是一个有效的模型对象(因为进入else分支的前提是$user->bankAccount存在),并且更新操作不会改变该对象的引用,只是同步数据库数据,所以返回资源时不会报错。
内容的提问来源于stack exchange,提问作者Mena
相关产品推荐
相关产品推荐

