class UserModel extends Model { public function role() { return $this->belognsTo(RoleModel::class , 'role_id' , 'id'); } }
$user = UserModel::with('role')->find(1); // $user->role 是一个 RoleModel // 更新 role 属性 $user->role = 'test'; // 正确输出 test var_dump($user->role); // 可是!!转换成 json 字符串后 // 你会发现,role 竟然仍是个模型!! // 并非你后面设置成的 test ! // 怪胎,丢失更新了?Laravel Bug ?? // 实际上不是!请看下属描述 var_dump(json_encode($user));
Laravel
的 Illuminate\Database\Eloquent\Model
实现了 JsonSerializable
接口,因此在调用 json_encode
进行序列化时,会调用 Model::jsonSerialize
方法,他这个方法返回的数据是:数据库
array_merge($attribute , $relation);
实际上你经过:json
$model->name = 'grayVTouch';
这种方式附加的新属性,Laravel
经过 __set
魔术方法重载,将其添加到 attribute
数组中,你是没法更改 relation
数组的!数组
而经过 模型关联 你却能够为 relation
数组新增单元!this
看到上面的数组合并方式,能够知道 relation
会覆盖掉 attribute
中的同名属性!!于是要特别注意:若是 relation
中有和 attribute
中同名的属性,请修改 relation
关联名称!若是不想修改 relation
名称,坚持前者覆盖后者,请:code
// 保存值 $attr = $model->attr; // 删除属性:attribute / relation 中的属性(Laravel 内部调用 __unset 魔术方法) unset($model->attr) // 从新设置值,仅设置到 attribute 数组 // relation 并不会被设置 $model->attr = $model;
Laravel
因为将模型属性拆分红两个数组,而他们实际上又同属于一个对象!因此若是存在同名属性,必然会产生 谁覆盖谁 的问题,attribute
一开始就是对应数据库表中的字段的,而 relation
是后面程序附加的,为了避免丢失更新,后者覆盖前者,很是正确。对象
虽然在使用过程当中应该当心避免 relation
和 attribute
撞上同名属性,但偶尔仍是会碰到的~,这个仍是稍微注意下就好,这并不是 Bug
,而是在当前的程序处理方式下必然会产生的一个正常现象。接口