【问题标题】:Cannot migrate with foreign key in Laravel 5.2无法在 Laravel 5.2 中使用外键迁移
【发布时间】:2016-06-24 06:37:47
【问题描述】:

我想创建两个表usersroles。我的代码如下:

2014_10_12_000000_create_users_table.php

<?php

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

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->integer('role')->unsigned();
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();

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

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

2016_03_09_004256_create_roles_table.php

<?php

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

class CreateRolesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
    }

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

当我运行php artisan migrate 时出现以下错误。

[照亮\数据库\查询异常] SQLSTATE[HY000]: 一般错误: 1005 Can't create table trucking.#sql-1240_44 (errno: 150 "外键约束格式不正确") (SQL: alter table users add constraint u sers_role_foreign 外键 (role) 引用 roles (id))

[PDO异常] SQLSTATE[HY000]: 一般错误: 1005 无法创建表trucking.#sql-1240_44 (errno: 150 "外键约束格式不正确")

【问题讨论】:

    标签: mysql laravel-5 foreign-keys database-migration laravel-5.2


    【解决方案1】:

    您应该确保您的roles 表迁移在users 表迁移之前运行。默认情况下,在 Laravel 中,您已经创建了 users 表迁移,所以如果您更改了它的代码,然后添加了 roles 迁移,它将无法工作。您应该更改usersroles 迁移文件名,以确保roles 表迁移文件开头的时间戳在users 表之前。

    例如你可能有这样的情况:

    2014_10_12_000000_create_users_table.php
    2015_10_12_123552_create_roles_table.php
    

    你应该重命名文件以使其如下:

    2015_10_12_123652_create_users_table.php
    2015_10_12_123552_create_roles_table.php
    

    当然,我假设您仅在开发期间使用这些迁移,并且尚未投入生产。

    【讨论】:

    • @smartrahat 没问题。您需要记住,您只能在现有表中创建外键,因此有时您需要创建 2 次迁移(没有外键)并在第 3 次迁移中在表之间添加外键。
    • 感谢您的提示。我会记住的。
    【解决方案2】:
     public function up()
        {
            Schema::create('users', function (Blueprint $table) {
                $table->increments('id');
                $table->string('firstname');
                $table->string('lastname');
                $table->text('slug');
                $table->string('email')->unique();
                $table->string('password', 60);
                $table->decimal('fidbonus', 6, 2);
                $table->rememberToken();
                $table->timestamps();
            });
            Schema::create('Userinfos', function (Blueprint $table) {
               $table->increments('id');
               $table->integer('User_id')->unsigned();
               $table->foreign('User_id')->references('id')->on('Users');
               $table->string('address');
               $table->string('address2');
               $table->text('city');
               $table->string('zip');
               $table->string('country');
               $table->string('Phone');
               $table->timestamps();
           });
           Schema::create('password_resets', function (Blueprint $table) {
               $table->string('email')->index();
               $table->string('token')->index();
               $table->timestamp('created_at');
           });
        }
    

    【讨论】:

    • 我认为我们不能编写超过 1 个 'up()' 方法。如果需要,在同一个 'up()' 方法中,您可以使用 'Schema::create()' 两次,一个在另一个之下。
    • 是的,我复制并粘贴错了,但就是这样,我编辑它并从我自己的项目中添加和示例,谢谢
    【解决方案3】:
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('firstname');
            $table->string('lastname');
            $table->text('slug');
            $table->string('email')->unique();
            $table->string('password', 60);
            $table->decimal('fidbonus', 6, 2);
            $table->rememberToken();
            $table->timestamps();
        });
        Schema::create('Userinfos', function (Blueprint $table) {
           $table->increments('id');
           //$table->integer('User_id')->unsigned();
           $table->unsignedInteger('User_id');
           //$table->foreign('User_id')->references('id')->on('Users');
             $table->foreign('User_id')->references('id')->on('Users')->onDelete('cascade')->onUpdate('cascade');
           $table->string('address');
           $table->string('address2');
           $table->text('city');
           $table->string('zip');
           $table->string('country');
           $table->string('Phone');
           $table->timestamps();
       });
       Schema::create('password_resets', function (Blueprint $table) {
           $table->string('email')->index();
           $table->string('token')->index();
           $table->timestamp('created_at');
       });
    }
    

    尝试上面的代码。它工作正常

    【讨论】: