Edited at

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で外部キー制約を無視して操作をした後に元に戻します。これで外部キー制約のあるテーブルが操作できるようになります。