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