前例
最近、会社のバックエンド プロジェクトが以前の laravel5.6 バージョンから laravel5.8 バージョンに変換およびアップグレードされました。大量の SQL 実行 それは間違いでしたが、古いバージョンのシステムではうまく動作したため、今日の穴を掘る旅が生まれました。
推奨: "laravel チュートリアル"
プロジェクト環境
古いシステム (linux laravel5.6 php7.2 mysql5. 7)
新しいシステムをアップグレードしました (linux laravel5.8 php7.2 mysql5.7)
laravel フレームワークのバージョンのみをアップグレードし、他の関連サービスの依存関係はアップグレードしませんでした。
ただし、SQL実行エラーが大量に発生しました。例外監視は以下の通りです:
分析プロセス
原因このサービス エラー これはビジネス ロジックの一部であり、以下のデモでシミュレートされています。
$pivot = UserRole::firstOrCreate([ 'user_id' => 3, 'role_id' => 3, ]); $this->addRoleHistory($user,$pivot->id); dd($pivot->id);
laravel5.6 バージョンでは、このコードは問題なく実行されますが、バージョン 5.8 にアップグレードすると、大量のエラーが発生します。
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 関数を比較したところ、変更はなく、コード ロジックが正しく実行されていることがわかりました。
次に、model->save() 関数のコードを読み続けます、存在しないデータが insertAndSetId を通じて挿入されていることを確認します。関数と主キーは ID#ただし、insertAndSetId 関数はインクリメントなどのメンバー属性によって制御されます。属性のデフォルト値は true
## です。#この属性が変更されると、次のステップが実行されます。このメンバー属性は操作されましたか?
そこで、早速5.8のピボットモデルのソースコードを確認してみました。最終的に、5.8の中間テーブルPivot Classにインクリメントが設定されていることがわかりました。デフォルトでは false に設定されているため、データは正常に挿入されましたが、挿入後の主キー ID が設定されていないため、残りのサービスがクラッシュし、正常に実行できなくなりました...
修復計画
各ピボットで、クラスの増加する属性値を再度上書きし、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で調べてみましたが、やはり見つかりませんでした。このジョークの理由。
最終的には、変更によって生じた問題は正常に修復されました。また、UT の報道内容にはまだもっと注意を払う必要があることを思い出させてくれました。後続のバージョンアップグレードでのバージョン互換性変更テストにより、プロジェクトの品質を多面的に確保します。
以上が消えたPivotモデルID (Laravelの落とし穴日記)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。