【问题标题】:Laravel :: Best way to update a foreign keyLaravel :: 更新外键的最佳方法
【发布时间】:2016-11-20 12:38:55
【问题描述】:

我有这个迁移文件

Schema::create('table_one', function(Blueprint $table) 
{ 
    $table->increments('id'); 
    $table->string('name'); 
    $table->integer('table_two_id')->unsigned(); 
    $table->foreign('table_two_id')->references('id')->on('table_two'); 
    $table->timestamps(); 
});

我想更新以使其 ->onDelete('cascade');

$table->foreign('table_two_id')->references('id')->on('table_two')->onDelete('cascade');

最好的方法是什么?

有没有类似 ->change();

谢谢

【问题讨论】:

    标签: php database laravel laravel-5.1


    【解决方案1】:

    删除外键,然后再次添加并运行迁移。

    public function up()
    {
        Schema::table('table_one', function (Blueprint $table) {
            $table->dropForeign(['table_two_id']);
    
            $table->foreign('table_two_id')
                ->references('id')
                ->on('table_two')
                ->onDelete('cascade');
        });
    }
    

    【讨论】:

    • 这确实是有道理的,因为 MySQL 会以同样的方式做,在这种情况下 MySQL 没有“变化”。但是,对于这种情况,我希望在 Laravel 级别上有一个 wrapper/single_command。谢谢。
    • 有数据不能删除,如何重新获取数据?在这种情况下,应该创建一个新列,然后制作一个脚本将数据从旧列复制到新列,然后将其删除,但这不是最好的方法,这是我的观点。我们可以安装:composer 需要学说/dbal 然后轻松更改它: $table->foreignId('table_two_id') ->nullable()->change()
    【解决方案2】:

    Christopher K. 是对的,在 Laravel 文档中说:

    要删除外键,您可以使用 dropForeign 方法。外键约束使用与索引相同的命名约定。因此,我们将连接表名和约束中的列,然后在名称后面加上“_foreign”

    $table->dropForeign('posts_user_id_foreign'); 
    

    或者,您可以传递一个 array 值,该值将在删除时自动使用常规约束名称:

    $table->dropForeign(['user_id']);
    

    https://laravel.com/docs/5.7/migrations#foreign-key-constraints

    【讨论】:

    • 感谢您的回答,但是这种命名约定既不是强制性的,也不可靠。我不断达到 foreign_key_name_length 的限制并重命名不重命名依赖外键的列。所以我对@Borut Flis 的回答很满意。
    【解决方案3】:
    1. composer require doctrine/dbal
    2. 在您的迁移文件中,执行以下操作:
        Schema::table('table_one', function (Blueprint $table) {
            $table->foreignId('table_two_id')
                  ->change()
                  ->constrained('table_two')
                  ->onDelete('cascade');
        });
    
    1. php artisan migrate

    【讨论】:

    • 通过重新定义constrained更新外键时会出现错误SQLSTATE[23000]: Integrity constraint violation: 1022 Can't write; duplicate key in table...,因此只需删除约束并说一些您只需要更新并与->change()链接的内容。在我的情况下,我刚刚更新了一个可以为空的外键,我不需要再次重新定义约束,因为它应该在创建迁移中调用,而不是改变一个,除非你想将约束更改为另一个表.
    【解决方案4】:

    你需要删除

         public function up()
        {
            Schema::table('<tableName>', function (Blueprint $table) {
                $table->dropForeign('<FK-name>');
                $table->dropColumn('<FK-columnName>');
            });
            Schema::table('<tableName>', function (Blueprint $table) {
                $table->foreignId('<FK-columnName>')->constrained()->cascadeOnDelete();
            });
    
        }
    

    有两个查询。在 Laravel 8 上工作

    【讨论】:

      【解决方案5】:

      如何通过控制器进行

      1- 设置一个 Rought:
      路线::get('foreignkeyforimg', "foreignkey@index"); 2- 使用外键名称创建控制器。
      3- 从迁移类扩展的外键控制器。
      4- 转到数据库并从表中手动删除旧的主键

      namespace App\Http\Controllers;
      
      use Illuminate\Http\Request;
      use Illuminate\Support\Facades\DB;
      use Illuminate\Support\Facades\Validator;
      use Illuminate\Support\Facades\Schema;
      use Illuminate\Database\Migrations\Migration;
      use Illuminate\Database\Schema\Blueprint;
      
      class Foreignkey extends Migration
      {
          function index(){
      
              Schema::table('images', function (Blueprint $table) {
      
      
                  $table->foreign('sub_cat_id')
                     ->references('id')
                      ->on('subcategories')
                      ->onDelete('cascade');
              });
          }
      }
      

      【讨论】:

      • 你能解释一下为什么有人应该使用控制器来做到这一点吗? “转到数据库并删除”是什么意思?如果您为这些东西编写迁移,为什么要手动运行?
      • 因为,通过迁移,可能会伤害到其他数据库表。这是更新任何表的外键的简单方法。这对新手来说非常简单
      • 请通过编辑您的答案进一步解释:您所说的“伤害”是什么意思?大多数主要的 PHP 脚本在迁移中运行这样的东西,我从来没有听说过更改索引会伤害任何数据库
      • 你的函数不会更新,而是创建一个外键,如果外键存在它就不起作用。问题是关于更新外键。
      • 读取点 4... 4- 转到数据库并从表中手动删除旧的主键
      猜你喜欢
      • 2014-12-13
      • 1970-01-01
      • 2021-03-24
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-07
      • 2013-12-20
      相关资源
      最近更新 更多