Laravel关联模型属性修改报错:Indirect modification of overloaded property无效果
解决Laravel中
Indirect modification of overloaded property App\User::$profile has no effect报错 这个报错我之前在Laravel里操作关联模型时也碰到过,其实根源是Laravel关联属性的重载机制导致的——你直接通过$user->profile->xxx修改属性时,因为$user->profile是魔术方法动态生成的重载属性,这种间接修改没法正确触发模型的属性更新,所以才会报这个错。
结合你的代码来看,问题就出在你直接链式修改$user->profile的属性上,咱们可以通过两种方式解决:
方法一:先取出Profile实例再修改
先把关联的Profile模型单独赋值给一个变量,再对这个变量做属性修改,最后保存,这样就能绕过重载属性的限制:
public function update(Request $request, $id) { $this->validate($request, [ 'name' => 'required', 'email' => 'required|email', 'facebook' => 'required|url', 'youtube' => 'required|url' ]); $user = Auth::user(); // 先把profile实例取出来单独存储 $profile = $user->profile; if($request->hasFile('avatar')) { $avatar = $request->avatar; $avatar_new_name = time() . $avatar->getClientOriginalName(); $avatar->move('uploads/avatars', $avatar_new_name); $profile->avatar = 'uploads/avatars/' . $avatar_new_name ; $profile->save(); } // 更新User模型的属性 $user->name = $request->name; $user->email = $request->email; $user->save(); // 更新Profile模型的属性 $profile->facebook = $request->facebook; $profile->youtube = $request->youtube; $profile->about = $request->about; $profile->save(); if($request->has('password')) { $user->password = bcrypt($request->password); $user->save(); } Session::flash('success', 'Account profile updated.'); return back(); }
方法二:使用fill批量赋值(更简洁)
如果你的Profile模型已经设置了可填充字段,用fill方法一次性填充属性会更简洁,同样能避开重载属性的问题:
首先要确保App/Profile.php里的$fillable包含所有你要更新的字段:
// App/Profile.php protected $fillable = ['facebook', 'youtube', 'about', 'avatar'];
然后修改update方法:
public function update(Request $request, $id) { $this->validate($request, [ 'name' => 'required', 'email' => 'required|email', 'facebook' => 'required|url', 'youtube' => 'required|url' ]); $user = Auth::user(); // 先收集Profile需要更新的字段 $profileData = $request->only(['facebook', 'youtube', 'about']); if($request->hasFile('avatar')) { $avatar = $request->avatar; $avatar_new_name = time() . $avatar->getClientOriginalName(); $avatar->move('uploads/avatars', $avatar_new_name); $profileData['avatar'] = 'uploads/avatars/' . $avatar_new_name ; } // 用update方法更新User,fill+save更新Profile $user->update($request->only(['name', 'email'])); $user->profile->fill($profileData)->save(); if($request->has('password')) { $user->update(['password' => bcrypt($request->password)]); } Session::flash('success', 'Account profile updated.'); return back(); }
额外要检查的点
- 确认
User模型的hasOne关联定义正确:
// App/User.php public function profile() { return $this->hasOne(Profile::class); }
- 确认
Profile模型的belongsTo关联指向正确:
// App/Profile.php public function user() { return $this->belongsTo(User::class); }
内容的提问来源于stack exchange,提问作者Caleb Oki
相关产品推荐
相关产品推荐

