首頁  >  文章  >  php框架  >  消失的Pivot模型ID(Laravel踩坑日記)

消失的Pivot模型ID(Laravel踩坑日記)

藏色散人
藏色散人轉載
2020-04-20 11:53:202996瀏覽

前因

最近公司後端專案進行了改造升級,由之前的laravel5.6版本升級到了laravel5.8版本,升級後系統產生了不少SQL執行錯誤,但是在舊版系統運作的好好的,於是就產生了今日的扒坑之旅。

推薦:《laravel教學

專案環境

舊系統(linux laravel5.6 php7.2 mysql5. 7)

升級後新系統(linux laravel5.8 php7.2 mysql5.7)

只單純升級了laravel框架版本,並無升級其他相關服務依賴.

但是卻出現大量的SQL執行錯誤,異常監控如下:

消失的Pivot模型ID(Laravel踩坑日記)

#分析過程

導致這段服務出錯的是這樣的一段業務邏輯,下面透過一段demo來模擬.

$pivot = UserRole::firstOrCreate([
    'user_id' => 3,
    'role_id' => 3,
]);
$this->addRoleHistory($user,$pivot->id);
dd($pivot->id);

在laravel5.6版本中這段程式碼運行起來毫無問題,但升級到5.8版本中就會引發大量的SQL執行錯誤,就像下面這樣.

laravel5.6:
    dd($pivot->id); //10002
laravel5.8:
    dd($pivot->id); //null

在5.6中保存中的資料還能正常獲取到ID,在5.8中怎麼就不行了呢,於是馬上去查看了laravel5.8的發行說明,也沒有發現Pivot模型取消取得自增ID的改動,於是開始進行5.8源碼查閱。 。 。

首先對5.6和5.8的firstOrCreate函數進行了對比,發現無改動,程式碼邏輯執行無誤。

消失的Pivot模型ID(Laravel踩坑日記)

然後繼續翻閱model->save()函數的程式碼

,發現不存在的資料是透過insertAndSetId該函數插入資料並設定主鍵ID

消失的Pivot模型ID(Laravel踩坑日記)

但insertAndSetId函數又是透過incrementing這樣的一個成員屬性來控制的,屬性的預設值是true

消失的Pivot模型ID(Laravel踩坑日記)

#當這個屬性變更時就不會執行者一步驟,難道這個成員屬性在被操作過了?

於是立刻查看了5.8的pivot模型原始碼.

消失的Pivot模型ID(Laravel踩坑日記)

最終發現是5.8的在中間表Pivot Class預設將incrementing設定成了false,所以資料被成功插入,但是沒有設定插入後的主鍵ID,造成剩餘服務崩潰,沒能正常運行...

#修復方案

在每個Pivot Class中重新覆寫incrementing屬性值為true即可.

class UserRole extends Pivot
{
    public $incrementing = true;
    protected $fillable = [
        'user_id',
        'role_id',
    ];
}

修復後:

laravel5.8:
    dd($pivot->id); //10003

後記

於是又去仔細看了一遍laravel5.7~laravel5.8發行說明,發現依然沒有提到這個改動的原因,於是又去google了一遍,依然沒有找到這個梗的原因所在.

消失的Pivot模型ID(Laravel踩坑日記)

#最後還是成功修復掉了該處改動帶來的問題,也提醒了我們在後續版本升級時還是需要多注重UT的覆蓋及版本兼容改動測試,多個維度來保證項目質量。

以上是消失的Pivot模型ID(Laravel踩坑日記)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除