Laravel :: 更新外键的最佳方法
Posted
技术标签:
【中文标题】Laravel :: 更新外键的最佳方法【英文标题】:Laravel :: Best way to update a foreign key 【发布时间】: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();
谢谢
【问题讨论】:
【参考方案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】:composer require doctrine/dbal
在您的迁移文件中,执行以下操作:
Schema::table('table_one', function (Blueprint $table)
$table->foreignId('table_two_id')
->change()
->constrained('table_two')
->onDelete('cascade');
);
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- 转到数据库并从表中手动删除旧的主键以上是关于Laravel :: 更新外键的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章