【问题标题】:laravel migration best way to add foreign keylaravel 迁移添加外键的最佳方法
【发布时间】:2014-12-13 18:20:52
【问题描述】:

简单的问题:我是 Laravel 的新手。我有这个迁移文件:

Schema::create('lists', function(Blueprint $table) {
    $table->increments('id'); 
    $table->string('title', 255);
    $table->integer('user_id')->unsigned(); 
    $table->foreign('user_id')->references('id')->on('users'); 
    $table->timestamps();
});

我想更新它以添加onDelete('cascade')

最好的方法是什么?

【问题讨论】:

    标签: laravel foreign-keys migration


    【解决方案1】:

    首先,您必须将 user_id 字段设为索引:

    $table->index('user_id');
    

    之后,您可以使用级联操作创建外键:

    $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
    

    如果你想通过新的迁移来做到这一点,你必须首先删除索引和外键,然后从头开始做所有事情。

    在 down() 函数上你必须这样做,然后在 up() 上做我上面写的:

    $table->dropForeign('lists_user_id_foreign');
    $table->dropIndex('lists_user_id_index');
    $table->dropColumn('user_id');
    

    【讨论】:

    • 为什么不:$table->dropForeign('user_id); $table->dropIndex('user_id');
    • 我试过了:$table->dropForeign('user_id'); $table->dropIndex('user_id'); $table->dropColumn('user_id');它似乎奏效了。
    【解决方案2】:
    Schema::create('roles',function(Blueprint $table){
    
        $table->bigIncrements('id');
        $table->string('name');
        $table->timestamps();
    
    });
    
    Schema::create('permissions',function(Blueprint $table){
    
        $table->unsignedBigInteger('role_id');
        $table->foreign('role_id')->references('id')->on('roles');
        $table->string('permission');
    
    });
    

    【讨论】:

      【解决方案3】:

      在 Laravel 7 中可以在一行中完成

      $table->foreignId('user_id')->constrained()->cascadeOnDelete();

      【讨论】:

        【解决方案4】:
        $table->integer('user_id')->unsigned();
        $table->foreign('user_id')->references('id')->on('users');
        

        在此示例中,我们声明 user_id 列引用 users 表中的 id 列。确保首先创建外键列! user_id 列被声明为无符号,因为它不能有负值。

        您还可以为约束的“删除时”和“更新时”操作指定选项:

        $table->foreign('user_id')
              ->references('id')->on('users')
              ->onDelete('cascade');
        

        要删除外键,您可以使用 dropForeign 方法。外键使用与其他索引类似的命名约定:

        $table->dropForeign('posts_user_id_foreign');
        

        如果您是 LaravelEloquent 的新手,请尝试 laracasts 上的 Laravel From Scratch 系列。对于初学者来说,这是一本很好的指南。

        【讨论】:

          【解决方案5】:

          假设你有两个表 student 和 section ,你可以参考以下两个表结构来添加外键和制作 onDelete('cascade') 。

          表-1:

          public function up()
          {
              Schema::create('student', function (Blueprint $table) {
                  $table->id();
                  $table->string('name');
                  $table->string('address');
                  $table->string('phone');
                  $table->string('about')->nullable();
                  $table->timestamps();
              });
          }
          

          表 - 2:

          public function up()
          {
              Schema::create('section', function (Blueprint $table) {
                  $table->id();
                  $table->bigInteger('student_id')->unsigned()->index()->nullable();
                  $table->foreign('student_id')->references('id')->on('student')->onDelete('cascade');
                  $table->string('section')->nullable();
                  $table->string('stream')->nulable();
                  $table->timestamps();
              });
          }
          

          希望对你有所帮助-:) 你可以从here阅读全文。

          【讨论】:

            【解决方案6】:

            您应该创建一个新的迁移文件,比如说“add_user_foreign_key.php”

            public function up()
            {
                Schema::table('lists', function(Blueprint $table)
                {
                     $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
                });
            }
            
            /**
             * Reverse the migrations.
             *
             * @return void
             */
            public function down()
            {
                Schema::table('lists', function(Blueprint $table)
                {
                $table->dropForeign('user_id'); //
                });
            }  
            

            奔跑

             php artisan migrate
            

            【讨论】:

              【解决方案7】:

              Laravel 7.x 外键约束

              Laravel 还支持创建外键约束,用于在数据库级别强制引用完整性。例如,让我们在 posts 表上定义一个 user_id 列,它引用用户表上的 id 列:

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

              由于这种语法相当冗长,Laravel 提供了额外的、更简洁的方法,这些方法使用约定来提供更好的开发者体验。上面的例子可以这样写:

              Schema::table('posts', function (Blueprint $table) {
                  $table->foreignId('user_id')->constrained();
              });
              

              来源:https://laravel.com/docs/7.x/migrations

              【讨论】:

              • 我得到外键格式不正确。 $table->foreignId('category_id')->constrained('categories')->onDelete('set null')->onUpdate('cascade');
              【解决方案8】:

              从 Laravel 8 开始:

              $table->foreignIdFor(OtherClass::class);
              

              这么简单:)

              • 确保 OtherClass 迁移文件在 EARLIER 之前运行(如往常一样按文件名日期)。
              • 如果 OtherClass id 不是自动递增的,则 otherclass_id 将具有 char 类型而不是 bigint,在这种情况下 ->

              改用这个:

              $table->foreignId('otherclass_id')->index()->constrained()->cascadeOnDelete();
              

              【讨论】:

              • 这使用起来要容易得多。感谢那。不知道为什么 Laravel 8.x 文档没有更新以包含此内容。是否仍然需要向下功能(如接受的答案所示)?
              • @JanWillemHuising 是的,您仍然需要定义如何恢复迁移,但这很容易。
              【解决方案9】:
              Schema::table('posts', function (Blueprint $table) {
                  $table->unsignedInteger('user_id');
              
                  $table->foreign('user_id')->references('id')->on('users');
              });
              

              【讨论】:

                【解决方案10】:

                如果您想在现有外键上添加onDelete('cascade'),只需删除索引并重新创建它们:

                public function up()
                {
                    Schema::table('lists', function($table)
                    {
                        $table->dropForeign('lists_user_id_foreign');
                
                        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
                    });
                }
                
                public function down()
                {
                    Schema::table('lists', function($table)
                    {
                        $table->dropForeign('lists_user_id_foreign');
                
                        $table->foreign('user_id')->references('id')->on('users');
                    });
                }
                

                【讨论】:

                  【解决方案11】:

                  我也在做同样的事情,但是得到了错误“id not exist”=>所以我改变了我的迁移文件如下:

                  题表迁移内容:

                  $table->id() => 应该改为 $table->increments('id')

                  Reply表中外键的定义:

                  $table->foreign('question_id')->references('id')->on('questions')->onDelete('cascade');

                  现在你的外键可以工作了。

                  【讨论】:

                    猜你喜欢
                    • 2016-02-11
                    • 2019-03-24
                    • 2017-03-27
                    • 2020-03-13
                    • 2020-01-23
                    • 2014-03-31
                    • 2021-08-30
                    • 2019-02-09
                    • 2020-09-21
                    相关资源
                    最近更新 更多