Почему при миграции с foreign key Laravel выдаёт ошибку?

При миграции (php artisan migrate) с foreign-key вылетает ошибка:

SQLSTATE[HY000]: General error: 1005 Can't create table slien_test.users (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table users add constraint users_city_id_foreign foreign key (city_id) references cities (id))

Пытался сделать связь сущности user и его города - city.

Миграция create_users_table:

public function up()
{
    Schema::create('users', function (Blueprint $table) {

        $table->id();
        $table->string('first_name');
        $table->string('last_name');
        $table->string('email')->unique();
        $table->string('password');
        $table->string('phone')->unique()->nullable();

        $table->unsignedBigInteger('city_id')->nullable();
        $table->foreign('city_id')->references('id')->on('cities');

        // new syntax
        // $table->foreignId('city_id')->constrained('cities');

        $table->timestamp('email_verified_at')->nullable();
        $table->rememberToken();
        $table->timestamps();
        $table->softDeletes('removed_at', 0);
    });
}

public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->dropForeign('city_id');
    })
    Schema::dropIfExists('users');
}

Миграция create_cities_table:

public function up()
{
    Schema::create('cities', function (Blueprint $table) {
        $table->id();
        $table->string('city');
    });
}

public function down()
{
    Schema::dropIfExists('cities');
}

В итоге долгие поиски причины ошибки не увенчались успехом. При чём я пробовал и новый синтаксис и старый (по документации). Сделал дополнительную миграцию add_foreign_key_in_users_table:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->unsignedBigInteger('city_id')->nullable();
        $table->foreign('city_id')->references('id')->on('cities');
    });
}

public function down()
{
    Schema::dropForeign('city_id');
}

После команды php artisan migrate миграции были выполнены успешно. Я предполагаю, что ошибка вылетает из-за того, что таблица, на которую ссылается связь в таблице users отсутствует. Но, почему тогда никто не выносит foreign-keys в другие миграции? Все пишут в той же самой миграции и ошибок никаких нет. Как решить проблему с этой ошибкой?

UPD:

users table

users_table

cities table

cities_table


Ответы (2 шт):

Автор решения: imvasha
$table->unsignedBigInteger('city_id')->nullable();
$table->foreign('city_id')->references('id')->on('cities');

// new syntax
// $table->foreignId('city_id')->constrained('cities_table');

Напишите зачем это все, и от версии зависит если свежее чем 5.8 то достаточно это прописать в миграции:

$table->integer('city_id')->nullable();

Остальное пишем в модели - это отношение согласно Вашей архитектуре например:

public function city()
    {
        return $this->belongsTo('App\City');
    }
→ Ссылка
Автор решения: E_K

Какой порядок у миграций? Сначала должна выполняться миграция для cities, а после уже users со связями. Для этого измените метку времени в имени файла. Или создайте файл миграций users после городов.

→ Ссылка