如何解决Laravel 迁移:“外键约束形成不正确”
当我尝试执行 PHP artisan migrate
或 PHP artisan migrate:refresh
时出现此错误,我的迁移失败:
errno: 150 "Foreign key constraint is incorrectly formed"
用户表(迁移成功)
public function up()
{
Schema::create('users',function (Blueprint $table) {
$table->integer('id',)->primary();
$table->string('name',255);
$table->string('surname',255);
$table->string('email',255)->unique();
$table->string('password',255);
$table->string('profile_image',255);
$table->string('profile_cover',255);
$table->rememberToken();
$table->char('token',255)->unique()->nullable()->default(null);
$table->enum('role',['user','driver',',merchant','storemanager','storeoperator','company','employee']);
$table->dateTime('created');
$table->dateTime('updated');
});
}
地址表(因错误而失败)
public function up()
{
Schema::create('address',function (Blueprint $table) {
$table->integer('id')->primary();
$table->string('address1');
$table->string('address2');
$table->string('city');
$table->integer('country')->unsigned();
$table->decimal('latitude');
$table->decimal('longitude');
$table->string('instructions');
$table->integer('default');
$table->integer('user')->unsigned();
$table->dateTime('created');
$table->dateTime('updated');
$table->foreign('country')->references('id')->on('country')->onUpdate('cascade');
$table->foreign('user')->references('id')->on('users')->onUpdate('cascade');
});
}
解决方法
使用 Laravel 等框架的原因之一是语法糖。通过遵循他们的约定,您可以编写更少的代码,并且不必考虑应用程序的“具体细节”。
您的做法与此相反,并且已经看到了后果。一旦您尝试建立模型及其关系,您将经历更多的痛苦。相反,您应该使用如下所示的迁移:
Script path
还有<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAddressesTable extends Migration
{
public function up()
{
// table names are plural of the object name
Schema::create('addresses',function (Blueprint $table) {
// automatically create an incrementing bigint column called 'id'
$table->id();
// name foreign ID columns correctly to save yourself trouble later
$table->foreignId('country_id')->constrained();
$table->foreignId('user_id')->constrained();
// specify lengths for your varchar columns
$table->string('address1',100);
$table->string('address2',100);
$table->string('city',100);
$table->decimal('latitude');
$table->decimal('longitude');
$table->string('instructions',100);
$table->integer('default');
// why would you define your own timestamp columns with non-standard names?
$table->timestamps();
});
}
}
表;您希望类似地更新其迁移。
users
,
每个表上的数据类型必须与键控列完全匹配。在 users
上,id 是一个有符号整数,在 address
上,user 是一个无符号整数。我建议为 id 使用无符号整数,因为它永远不会变为负数,并为您提供更高的上限。
在你--env
迁移而不是:
address
放置:
$table->integer('user')->unsigned();
FK 和引用键的类型应该相同。
,您可以将表用户的 id 更改为:
$table->id();
并将地址表 user
更改为 user_id
并尝试像这样更改外部 ID:
$table->foreignId('user_id')->constrained()->onDelete('cascade');
,
失败的原因是@aynber 提到的。键的数据类型必须匹配。
遵循 Laravel 命名主键和外键的最佳实践也很重要。主键应该是“id”,外键应该是表名(单数)下划线 id。例如,如果表名是 users,那么表 users 的外键应该是 'user_id'。
这里是表地址的例子(复数)
Schema::create('addresses',function (Blueprint $table) {
$table->id();
...
$table->foreignId('user_id')->constrained();
});
您不必提供表名或另一个表的主键,因为 Laravel 会从外键(user_id 转换为具有主键 id 的表用户)计算出来。稍后,当您创建雄辩的模型时,您可以从模型中留下一些信息。
class Address {
public function user()
{
return $this->belongsTo(User::class);
}
}
此处不必指定 $table
属性,也不必在 belongsTo
方法中提供外键或主键。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。