【Laravel8】親レコードをリレーション先の子レコードと一緒に削除する

はい、今回はリレーションがあるテーブルがあったときに親の削除と同時に子レコードの削除も行い多と思います。

というのも今回親レコードを削除しようとしたときに以下のエラーがでたのでそれを解決していきます。

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails

レコードを削除しようとしたときのエラー文一部

伝えたいこと

今回伝えたいことは、親レコードと対応している子レコードも一緒に削除する方法です。

もし、子レコードが存在するときに、親レコードが削除されるとエラーがでてしまうので、なぜ出るのかなどを説明しながら解決していきましょう!

そこでmigrationファイルの書きかたも徐々に覚えていきましょうね!

原因: 親レコードに紐づいている子レコードが削除されない。

今回エラーが起きたのは親レコードを削除しようとしたけど子レコードが残っているよ~おいていかないで―っていうエラーがでていたんですね。

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails
Code language: JavaScript (javascript)

なぜ、子レコードを置いたまま親のレコードは削除できないのか。

それはもしリレーション元のレコードがないとしたらデータの不整合性 が発生するからですね。

簡単に説明すると、論理的に矛盾が生じていますよ~ってこと。

子レコードからリレーション元のレコードを見に行こうとしたらあれ?ないじゃん!ってなるわけですね。

この不整合を解決させましょう!

解決策

今回の課題に対する解決策としては、migrationファイルで初めから親レコード消したらリレーション先の対応する子レコードも削除しちゃってねーっていう設定を入れます。

cascadeの設定を追加する。

では子レコード(リレーション先のレコード)のmigrationファイルにcascadeの設定を追加します。

cascadeについてはこちらのQiita記事で丁寧に記載されていました。

簡単に言うと、「参照先に何かあったらそれに合わせて自分も変化するよ~」っていう意味。

だと思っています!

ではcascadeの設定をmigrationファイルに追記していきますが、公式より記述方法があるのでそちらを参考にしてみます。

メソッド説明
$table->cascadeOnUpdate();更新をカスケードします。
$table->restrictOnUpdate();更新を制限します。
$table->cascadeOnDelete();削除をカスケードします。
$table->restrictOnDelete();削除を制限します。
$table->nullOnDelete();削除時に外部キーへNULLをセットします。
https://readouble.com/laravel/8.x/ja/migrations.html 参照

では書いていきます。

リレーション先(子レコードがある)migrationファイル

<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class Posts extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->string('post'); $table->timestamps(); $table->unsignedBigInteger('user_id'); //外部キー $table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete()->comment('user_idはusersテーブルのIDと紐づいている。'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('posts'); } }
Code language: HTML, XML (xml)

ここで、cascadeOnDelete() を利用しました。

こちらのアクションを指定することで、参照先(親レコード)が削除されると自動的に参照元(子レコード)も削除されるようになります!

最後に、再度migrationする必要があるので検証環境の為リフレッシュさせてtableを作りなおしておきました!

必要に応じてmigrationの対応をしてください!

//データベースをリフレッシュする。 php artisan migrate:refresh //seedingを使ってデータを入れなおす。 php artisan db:seed
Code language: JavaScript (javascript)

まとめ

データの整合性に関してはデータベースを取り扱ううえで大切なのでしっかり意識して作りましょう!

今回利用したのはcascadeOnDelete() でした!

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA