Как определить внешние ключи в миграции?

Эта проблема

Я хочу добавить внешние ключи в таблицы. Когда я запускаю свою первую миграцию create_posts_table, она выглядит так:

Schema::create('posts', function(Blueprint $table) {
    $table->engine = 'InnoDB';

    $table->increments('id');
    $table->unsignedInteger('user_id')->index();

    // . . .
});

Schema::table('posts', function(Blueprint $table)
{
    $table->foreign('user_id')->references('id')
          ->on('users')->onDelete('cascade');
});

Выдается следующая ошибка:

[Illuminate\Database\QueryException] SQLSTATE[HY000]:

Общая ошибка: 1215 Невозможно добавить ограничение внешнего ключа (SQL: изменить таблицу posts добавить ограничение posts_user_id_foreign внешний ключ (user_id) ссылается на users (id) при удалении каскада)

Это вызвано тем, что таблица users еще не создана, поэтому не удается создать внешний ключ, ссылающийся на пользователя, в таблице posts.

Возможное решение

Решением этой проблемы будет добавление внешних ключей с новой миграцией после создания всех таблиц. Однако мне он кажется хлипким.

Вопрос

Как я могу определить внешние ключи в миграциях соответствующих таблиц вместо того, чтобы добавлять их отдельно с другой миграцией после того, как все таблицы были созданы?


person Alex Lomia    schedule 04.06.2016    source источник


Ответы (2)


Вы можете выполнять несколько миграций в одном файле миграции. Если у вас есть таблица сообщений, в которой вы хотите внешний ключ для таблицы пользователей, но таблица пользователей еще не существует, вы должны либо сделать это в файле миграции таблицы пользователей после создания таблицы пользователей, либо вам нужно сделайте отдельную миграцию, как вы сказали. Вы не можете «сохранить» инструкции для дальнейшего использования при миграции.

person Joel Hinz    schedule 04.06.2016
comment
То есть это единственные варианты? - person Alex Lomia; 04.06.2016
comment
Боюсь, что так, насколько я знаю. - person Joel Hinz; 04.06.2016
comment
Спасибо за ответ - person Alex Lomia; 04.06.2016
comment
Просто для ясности, миграции выполняются в том порядке, в котором они создаются. Вы увидите, что каждый файл миграции имеет дату/время в начале имени файла. Настройте свои внешние ключи в файле миграции, который устанавливается после создания необходимых таблиц; создайте отдельную миграцию после настройки всех созданных миграций таблиц или измените порядок временных меток, связанных с вашими файлами миграции (хотя это не рекомендуется — лучше начать заново). - person SupaMonkey; 25.08.2018

В laravel хранятся отдельные файлы миграции для разных таблиц с индексацией, первичным ключом и внешними ключами.....

CreateUsersTable

class CreateUsersTable extends Migration
{

    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('email');
        $table->string('password', 60);            
        $table->enum('status', ['0', '1'])->default('0');
        $table->rememberToken();
        $table->nullableTimestamps();

        $table->unique('email');

        });
    }

    public function down()
    {
        Schema::drop('users');
    }
}

СоздатьPostsTable

class CreatePostsTable extends Migration
{

    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned();         

            $table->foreign('user_id')->references('id')->on('users');
        });
    }

    public function down()
    {
        Schema::drop('posts');
    }
}
person Shanka SMS    schedule 03.07.2016