New Laravel Project一次添加多个包含外键的表

时间:2018-02-14 04:13:45

标签: php laravel laravel-5

我启动了一个运行5.6的新laravel应用程序,并在运行迁移之前对我创建多个迁移的流程进行流线化。 我有大量的外键用于链接,以使我的数据库易于扩展。

我的问题是尝试引用迁移后期的数据库中的外键。我相信它不起作用,因为我试图引用的表还没有按操作顺序创建。

例: create_users_table迁移:

$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');

$table->integer('user_id')->nullable()->unsigned();
$table->foreign('user_id')->references('id')->on('users');

$table->integer('type_id')->nullable()->unsigned();
$table->foreign('type_id')->references('type_id')->on('types');

$table->integer('post_id')->nullable()->unsigned();
$table->foreign('post_id')->references('post_id')->on('posts');

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

Ex:create_types_table迁移:

            $table->increments('id');
            $table->string('type');

            $table->integer('user_id')->nullable()->unsigned();
            $table->foreign('user_id')->references('user_id')->on('users')->nullable();

            $table->integer('revenue_id')->nullable()->unsigned();
            $table->foreign('revenue_id')->references('revenue_id')->on('revenue')->nullable();

            $table->integer('hours_id')->nullable()->unsigned();
            $table->foreign('hours_id')->references('hours_id')->on('hours')->nullable();

            $table->integer('project_id')->nullable()->unsigned();
            $table->foreign('project_id')->references('project_id')->on('projects')->nullable();

            $table->integer('type_id')->nullable()->unsigned();
            $table->foreign('type_id')->references('id')->on('types');
            $table->timestamps();

我在所有表格中都遵循相同类型的模式。 我想我的问题是;是因为这些表还没有创建,所以没有什么可以引用的?有没有办法解决这个问题,还是我需要重新启动,创建所有表,然后为每个表添加另一个迁移以添加外键?

这可能是一个愚蠢的问题,我对laravel相当新鲜。这是我第一次尝试在应用程序中尽早添加关系。

3 个答案:

答案 0 :(得分:4)

您无法引用尚未创建的表。您可以单独Schema::create / Schema::table(如@ceejayoz所说)来实现此目的,以便将所有配置放在单个迁移文件中:

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->increments('user_id');
        // the rest of the fields
        $table->timestamps();
    });

    Schema::create('some-other-table', function (Blueprint $table) {
        $table->increments('other_table_id');
        // the rest of the fields
        $table->timestamps();
    });

    Schema::table('some-other-table', function (Blueprint $table) {
        $table->foreign('some_field_id')->references('user_id')->on('users');
    });


}

答案 1 :(得分:1)

外键及其关系不能为空,请确保删除->nullable()

$table->unsignedInteger('user_id');

另外,除非你有多对多的关系Learn more about it,否则你在两个表上放置外键关系是错误的。

建立关系时:

  1. 外键和主键必须相同(increments()表示它是整数,无符号和自动递增)。
  2. 您不能与不存在的表格建立关系(在 Laravel 中,当您运行php artisan migrate时,它会读取从最旧到最新的迁移[按创建日期] )。
  3. $table->foreign('type_id')->references('id')->on('types');表中的Users将其引用到Types表的主键,我假设在创建新迁移时默认为id laravel。< / LI>

    这意味着它运行时:

    $table->integer('type_id')->unsigned();
    $table->foreign('type_id')->references('type_id')->on('types');
    

    它正在尝试引用您在type_id表格中使用列type_id创建的types列,在这种情况下它不存在,因为它正在启动使用create_users_table迁移。

    我的解决方案:
    从所有表中删除所有关系,只创建将成为外键的列,如$table->unsignedInteger('type_id');
    在终端中运行php artisan make:migration create_foreign_keys,打开它然后放入其中:

    Schema::table('users', function (Blueprint $table) {
        $table->foreign('type_id')->references('id')->on('types');
    });
    Schema::table('types', function (Blueprint $table) {
        $table->foreign('whatever_id')->references('id')->on('whatever_table');
    });
    // ....
    

    这样您可以创建所有表,然后单独分配外键 迁移。

答案 2 :(得分:0)

由于您无法引用不存在的表,因此您可以尝试在没有属性的情况下创建所有表,例如。 :

Schema::create('table1', function (Blueprint $table) {
    $table->increments('table1_id');
    $table->int('table1_int');
});
Schema::create('table2', function (Blueprint $table) {
    $table->increments('table2_id');
    $table->int('table2_int');
});
Schema::create('table3', function (Blueprint $table) {
    $table->increments('table3_id');
    $table->int('table3_int');
});

之后您可以分配外键约束和关系,例如:

Schema::table('table2', function (Blueprint $table) {
    $table->foreign('some_field_id')->references('table1_id')->on('table1');
});
Schema::table('table3', function (Blueprint $table) {
    $table->foreign('some_field_id')->references('table2_id')->on('table2');
});