简体   繁体   中英

Laravel - cannot add foreign key constraint, but table still migrates to DB?

I am trying to create a pivot table called 'role_user' this table is the relationship between my 'user' table and 'role' table. When i try to migrate 'role_user' table I have the following error:

Illuminate\Database\QueryException 

  SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `role_user` add constraint `role_user_user_id_foreign` foreign key (`user_id`) references `users` (`id`))

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:669
    665|         // If an exception occurs when attempting to run a query, we'll format the error
    666|         // message to include the bindings with SQL, which will make this exception a
    667|         // lot more helpful to the developer instead of just the database's errors.
    668|         catch (Exception $e) {
  > 669|             throw new QueryException(
    670|                 $query, $this->prepareBindings($bindings), $e
    671|             );
    672|         }
    673| 

I would like to add that the 'role_user' table successfully migrates to the DB despite this error.

The code for my 'role_user' table is below:

<?php

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

class CreateRoleUserPivotTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('role_user', function (Blueprint $table) {
            $table->unsignedInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users');

            $table->unsignedInteger('role_id');
            $table->foreign('role_id')->references('id')->on('roles');
        });
    }

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

I am new to laravel so i would appreciate any help. Thanks.

Data types have to be the same before you can add a constraint. With Laravel, your id field will be, unless you have changed it, a BigInteger. So, you need to add the role_id as an unsignedBigInteger.

$table->unsignedBigInteger('role_id');

As indicated by @I Gusti Ngurah Arya Bawanta, you also need to check that the users and roles exist before the pivot table. One simple way of ensuring this, is to check the first part of your migration file name. For example, 2014_10_12_000000_create_users_table.php indicates that the migration was created on 10/12/2014 at midnight. Your migrations will be ran by chronological order as indicated by that date on each migration. If needed, you can change that date portion to ensure that the tables are migrated in the correct order. Also, in reading your comments above, InnoDB does support foreign keys.

Once you make the changes I mentioned, run php artisan migrate:fresh. That will delete your current tables and start the migration process all over again.

The table migration is simply stopped when there are errors. There are some notes for your problem :

  1. The table name is different in create and drop, in create it is role_user but in drop it is role_user_pivot
  2. There's no primary key, it is important for table to have one
  3. The users and roles table should be exist before role_user table
  4. Adding cascade if needed, if not, it's ok

Your code should looks like this :

<?php

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

class CreateRoleUserPivotTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('role_user', function (Blueprint $table) {
            $table->unsignedInteger('user_id');
            $table->unsignedInteger('role_id');

            $table->primary(['user_id', 'role_id']);
            $table->foreign('user_id')->references('id')->on('users');
            $table->foreign('role_id')->references('id')->on('roles');
        });
    }

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM