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
,而是在當前的程序處理方式下必然會產生的一個正常現象。接口