person表 | |
---|---|
id | integer |
name | string |
address_rel表 | |
---|---|
id | integer |
lsc | integer (11 or 101) 此處在 MorphMap 定義對映關係 |
lid | integer |
address | integer |
address表 | |
---|---|
id | integer |
country | integer 國家ID |
province | integer 省ID |
city | integer 市區ID |
….. | 省略 |
首先,在AppServiceProvider我定義了morphMap:
Relation::morphMap([
'11' => Person::class,
'101' => Company::class,
]);
然後,在Person模型中,定義了獲取所有地址的方法:
public function address()
{
return $this->morphToMany(
Address::class, //地址表
'lsc', //多型關聯表中的對映表關係
'address_rel', //多型關聯表
'lid', //對映表ID
'address' //地址ID
);
}
最後,在 Controller 層,來獲取 Person 的所有地址:
$person = Person::find(1);
$person->address->toArray();
此時報錯資訊為:
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'lu_address_rel.lsc_type' in 'field list' (SQL: select `lu_address`.*, `lu_address_rel`.`lid` as `pivot_lid`, `lu_address_rel`.`address` as `pivot_address`, `lu_address_rel`.`lsc_type` as `pivot_lsc_type` from `lu_address` inner join `lu_address_rel` on `lu_address`.`id` = `lu_address_rel`.`address` where `lu_address_rel`.`lid` = 56 and `lu_address_rel`.`lsc_type` = 11)"
透過上面可以看到,我們傳的 lsc 在 Laravel 中自動拼上了 _type,而 lid 是正確的,這時我們透過追查原始碼發現
如上圖所示,在我們傳入 $foreignPivotKey 欄位時,Laravel 做了相應的判斷處理,如果傳了這個欄位(也就是 lid),則完全使用使用者傳入的值,否則將拼接為 $name . ‘_id’ ,這裡的 $name 就是我們在 Model 中傳入的第二個引數
那麼我們接著來看 $name 引數是如何處理的
追查到這裡發現,Laravel 是直接將使用者傳入的 $name 引數拼上了 _type ,這就出現了上面的報錯資訊。
透過以上資訊發現我們如果要用到 MorphToMany 方法,就必須要把表設計改為 Laravel 的規範,否則,目前的 Laravel 版本中用 MorphToMany 是完成不了需求的。
本作品採用《CC 協議》,轉載必須註明作者和本文連結