Help us understand the problem. What is going on with this article?

Laravelで外部キー制約のあるテーブルを操作する。

More than 1 year has passed since last update.

Laravelで外部キー制約の操作につまづいたので、解決策をまとめました。

テーブルの詳細

table_sample.php
function run()
{
    Schema::create('parents', function (Blueprint $table) {
        $table->increments('id');
        $table->string('email', 60)->unique();
        $table->string('name', 30);
        $table->timestamps();
        $table->softDeletes();
    });
    Schema::create('children', function (Blueprint $table) {
        $table->increments('id');
        $table->string('email', 60);
        $table->foreign('email')->references('email')->on('parents')->onDelete('cascade');
        $table->string('name', 30);
        $table->timestamps();
        $table->softDeletes();
    });
{

親テーブル「parents」のemailを参照する子テーブル「children」を想定したモデルです。

失敗例

上記の状態で以下のコードを実行します。

seeder_fail_sample.php
public function run()
{
    Model::unguard();

    DB::table('parents')->truncate();
    $this->call('ParentsSeeder');


    Model::reguard();
}

このコードはシードデータを入れる際にテーブルをトランケートするといったコードになります。

$ php artisan db:seed

上記のコマンド」を呼び出すと、以下のエラーが出てしまいます。

SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table referenced in a foreign key constraint

外部キー制約のためトランケートができませんって言われています。

解決策

seeder_success_sample.php
public function run()
{
    Model::unguard();

    DB::statement('SET FOREIGN_KEY_CHECKS=0;');

    DB::table('parents')->truncate();
    $this->call('ParentsSeeder');

    DB::statement('SET FOREIGN_KEY_CHECKS=1;');

    Model::reguard();
}

SET FOREIGN_KEY_CHECKSで外部キー制約を無視して操作をした後に元に戻します。これで外部キー制約のあるテーブルが操作できるようになります。

Asuforce
こんにちは、本業は SRE ですが色々やってます
https://asuforce.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away