简体   繁体   English

Laravel - 无法添加外键约束,但表仍然迁移到数据库?

[英]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.我正在尝试创建一个名为“role_user”的数据透视表,该表是我的“用户”表和“角色”表之间的关系。 When i try to migrate 'role_user' table I have the following error:当我尝试迁移“role_user”表时,出现以下错误:

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.我想补充一点,尽管出现此错误,“role_user”表仍成功迁移到数据库。

The code for my 'role_user' table is below:我的“role_user”表的代码如下:

<?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.我是 laravel 的新手,所以我很感激任何帮助。 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.使用 Laravel,你的 id 字段将是一个 BigInteger,除非你改变了它。 So, you need to add the role_id as an unsignedBigInteger.因此,您需要将 role_id 添加为 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.正如@I Gusti Ngurah Arya Bawanta 所指出的,您还需要检查数据透视表之前是否存在用户和角色。 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.例如,2014_10_12_000000_create_users_table.php 表示迁移是在 10/12/2014 午夜创建的。 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.此外,在阅读您上面的评论时,InnoDB 确实支持外键。

Once you make the changes I mentioned, run php artisan migrate:fresh.完成我提到的更改后,运行 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表名在create和drop中不同,在create中是role_user ,在drop中是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 usersroles表应该存在于role_user表之前
  4. Adding cascade if needed, if not, it's ok如果需要,添加cascade ,如果没有,没关系

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');
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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