我试图在Laravel中创建外键,但是当我使用artisan迁移我的表时,我抛出了以下错误:

[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL
: alter table `priorities` add constraint priorities_user_id_foreign foreign 
key (`user_id`) references `users` (`id`))     

我的迁移代码如下:

优先级迁移文件

public function up()
{
    //
    Schema::create('priorities', function($table) {
        $table->increments('id', true);
        $table->integer('user_id');
        $table->foreign('user_id')->references('id')->on('users');
        $table->string('priority_name');
        $table->smallInteger('rank');
        $table->text('class');
        $table->timestamps('timecreated');
    });
}

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

用户迁移文件

public function up()
{
    //
    Schema::table('users', function($table)
    {
    $table->create();
    $table->increments('id');
    $table->string('email');
    $table->string('first_name');
    $table->string('password');
    $table->string('email_code');
    $table->string('time_created');
    $table->string('ip');
    $table->string('confirmed');
    $table->string('user_role');
    $table->string('salt');
    $table->string('last_login');

    $table->timestamps();
    });
}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    //
        Schemea::drop('users');
}

关于我做错了什么,我现在想要得到这个,因为我有很多表,我需要创建例如用户,客户端,项目,任务,状态,优先级,类型,团队。理想情况下,我想创建表持有这些数据与外键,即clients_project和project_tasks等。

希望有人能帮我开始。


当前回答

我在使用Laravel 5.8时也遇到了同样的问题。在仔细研究laravel文档之后,还有Migrations & bigIncrements。我解决这个问题的方法是通过添加主键“$table->bigIncrements('id')”到与表“用户”及其关联相关的每一个表,在我的情况下,表“角色”。最后,我有“$table->unsignedBigInteger”用于将角色关联到用户(多对多),即表“role_user”。

1. Users table

    Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

2. Roles Table
    Schema::create('roles', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('name')->unique();
        $table->string('display_name')->nullable();
        $table->string('description')->nullable();
        $table->timestamps();
    });

3. Table role_user
Schema::create('role_user', function (Blueprint $table) {
            $table->unsignedBigInteger('user_id');
            $table->unsignedBigInteger('role_id');
            $table->foreign('user_id')->references('id')->on('users')
                ->onUpdate('cascade')->onDelete('cascade');
            $table->foreign('role_id')->references('id')->on('roles')
                ->onUpdate('cascade')->onDelete('cascade');
            $table->primary(['user_id', 'role_id']);
        });

其他回答

其要点是,外部方法使用ALTER_TABLE将一个预先存在的字段转换为外键。所以在应用外键之前必须定义表类型。但是,它不必在单独的Schema::调用中。你可以在create中做这两件事,像这样:

public function up()
{
    Schema::create('priorities', function($table) {
        $table->increments('id', true);
        $table->integer('user_id')->unsigned();
        $table->foreign('user_id')->references('id')->on('users');
        $table->string('priority_name');
        $table->smallInteger('rank');
        $table->text('class');
        $table->timestamps('timecreated');
    });
}

还要注意,user_id的类型被设置为unsigned以匹配外键。

我们不能添加关系,除非创建了相关的表。Laravel根据迁移文件的日期顺序运行迁移。因此,如果您想要与第二个迁移文件中存在的表创建关系,则会失败。

我也遇到了同样的问题,所以我最后创建了一个迁移文件来指定所有关系。

Schema::table('properties', function(Blueprint $table) {
        $table->foreign('user')->references('id')->on('users')->onDelete('cascade');
        $table->foreign('area')->references('id')->on('areas')->onDelete('cascade');
        $table->foreign('city')->references('id')->on('cities')->onDelete('cascade');
        $table->foreign('type')->references('id')->on('property_types')->onDelete('cascade');
    });

    Schema::table('areas', function(Blueprint $table) {
        $table->foreign('city_id')->references('id')->on('cities')->onDelete('cascade');
    });

确保你的外分栏超过外分键栏的宽范围

我的意思是你的前键(在第二个表)必须是相同类型的你的ponter主键(在第一个表)

您的指针主键必须添加unsigned方法,让我显示:

在你的第一个迁移表上:

$table->increments('column_name'); //is INTEGER and UNSIGNED

在第二个迁移表上:

$table->integer('column_forein_name')->unsigned(); //this must be INTEGER and UNSIGNED
$table->foreign('column_forein_name')->references('column_name')->on('first_table_name');

另一个例子可以看出区别

在你的第一个迁移表上:

$table->mediumIncrements('column_name'); //is MEDIUM-INTEGER and UNSIGNED

在第二个迁移表上:

$table->mediumInteger('column_forein_name')->unsigned(); //this must be MEDIUM-INTEGER and UNSIGNED
$table->foreign('column_forein_name')->references('column_name')->on('first_table_name');

请参阅mysql数值类型表范围

这么简单!!

如果您第一次创建“priorities”迁移文件,Laravel首先运行“priorities”而“users”表不存在。

它如何向一个不存在的表添加关系!

解决方案:从“优先级”表中取出外键代码。你的迁移文件应该是这样的:

并添加到一个新的迁移文件,这里它的名字是create_prioritiesForeignKey_table,并添加这些代码:

public function up()
{        
    Schema::table('priorities', function (Blueprint $table) {          
        $table->foreign('user_id')
              ->references('id')
              ->on('users');                        
    });
}

为了在laravel中添加外键约束,我使用了以下方法:

创建列为外键,如下所示: 表- >美元整数(column_name) - >无符号(); 在(1)之后立即添加约束行,即。 表- >美元整数(column_name) - >无符号(); 表- >外国(column_name) - >引用(pk_of_other_table) - >(“other_table”);