场景恢复}}ErrorTheprogram$user=UserModel::with('role')->find(1);//$user->roleisaRoleModel//更新角色属性$user->role='test';//正确的输出testvar_dump($user->role);//但是!!转成json字符串后//你会发现role还是一个model!!//不是你后面设置的测试!//极客,丢失更新?Laravel错误??//其实并不是!请看从属说明var_dump(json_encode($user));原理概述Laravel的Illuminate\Database\Eloquent\Model实现了JsonSerializable接口,所以在调用json_encode进行序列化时,会调用Model::jsonSerialize方法,返回数据为:array_merge($attribute,$relation);事实上,你通过了:$model->name='grayVTouch';这样附加的新属性,Laravel通过__set魔术方法重载,添加到属性数组中,不能改变关系数组!但是对于模型关系,您可以将元素添加到关系数组!看到上面的数组合并方法,我们就知道relation会覆盖attribute中的同名属性!!所以要特别注意:如果relation中存在与属性同名的属性,请修改relation的关联名!如果您不想修改关系名称,坚持前者并覆盖后者,请://保存值$attr=$model->attr;//删除属性:attribute/relation中的属性(Laravel内部调用了__unset魔术方法)unset($model->attr)//重置值,只设置到属性数组//relation不会被设置$model->属性=模型;综合评价Laravel,因为模型属性拆分成两个数组,居然属于同一个对象!所以如果有同名的属性,就必然会出现谁覆盖谁的问题。属性一开始对应数据库表中的字段,关系是后面程序添加的。为了不丢失更新,后者覆盖了前者,这是非常正确的。虽然在使用过程中要注意避免relation和attribute与同名属性发生冲突,但是偶尔也会遇到~,这个还是注意一下比较好,这个不是bug,但是在当前的程序处理方式下不可避免会出现的一种正常现象。
