General error 1824 Failed to open the referenced table "テーブル名"

General error 1824 Failed to open the referenced table "テーブル名"

はじめに

本記事は、外部キー制約を含んだテーブルを作成する際に発生したエラーの解決方法を記述しています。

作成したいテーブル

作成したいテーブル構成は以下のようになっています。

db-er

マイグレーションファイルの内容です。

"2023_01_17_230401_create_products_table.php"
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id()->comment('id');
            $table->string('title', 255)->comment('タイトル');
            $table->string('product_code', 255)->unique()->comment('プロダクトコード');
            $table->string('description', 255)->comment('詳細説明');
            $table->unsignedBigInteger('category_id')->nullable()->comment('categoriesテーブルのid');
            $table->unsignedBigInteger('tag_id')->nullable()->comment('tagsテーブルのid');
            $table->string('thumbnail', 255)->comment('サムネイル画像のパス');
            $table->string('screenshot', 255)->comment('スクリーンショット画像のパス');
            $table->timestamps();

            $table->foreign('category_id')->references('id')->on('categories');
            $table->foreign('tag_id')->references('id')->on('tags');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('products');
    }
};
"2023_01_17_230410_create_categories_table.php"
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id()->comment('id');
            $table->string('name', 255)->comment('カテゴリ名');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('categories');
    }
};
"2023_01_17_230406_create_tags_table.php"
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('tags', function (Blueprint $table) {
            $table->id()->comment('id');
            $table->string('name', 255)->comment('タグ名');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('tags');
    }
};

原因

マイグレーションファイルの日付部分はその実行順序を決定します。

今回の場合、categoriestagsテーブルが作成されるよりも先にproductsテーブルが作成されようとし、それがエラーの原因となりました。

つまり、productsを作成した際に本来であれば作成されていなければならないcategoriesテーブルとtagsテーブルが存在していないので、productsテーブルの外部キー制約となっているcategory_idtags_idが見つからずエラーとなっています。

解決方法

2023_01_17_230401_create_products_table.phpファイルの日付の箇所を、他のcategoriesテーブルとtagsテーブルより後に作成されたように命名すれば解決します。

230401の箇所を230411にリネームして実行したら正しく作成されました。

注意点

ファイルをリネーム後、マイグレーションを実行した際にBase table or view already exists: 1050 Table 'products' already existsとエラーが出た場合は、productsテーブルが既に存在しています。

この場合は、php artisan migrate:reset を実行してすべてのマイグレーションをロールバックし、データベースをクリーンな状態に戻します。

そして再度 php artisan migrate を実行します。