【发布时间】:2018-07-11 18:07:22
【问题描述】:
我有以下迁移表:
class CreateQuizzesTable extends Migration
{
public function up()
{
Schema::create('quizzes', function (Blueprint $table) {
$table->increments('id');
$table->integer('customer_id')->unsigned()->nullable();
$table->string('name');
$table->foreign('customer_id')->references('id')->on('customers')->onDelete('set null');
});
}
public function down()
{
Schema::dropIfExists('quizzes');
}
}
还有
class CreateCustomersTable extends Migration
{
public function up()
{
Schema::create('customers', function (Blueprint $table) {
$table->increments('id');
$table->integer('quiz_id')->unsigned()->nullable();
$table->string('name')->unique();
$table->string('password');
$table->foreign('quiz_id')->references('id')->on('quizzes')->onDelete('set null');
});
}
public function down()
{
Schema::dropIfExists('customers');
}
}
客户可以创建(并因此拥有)多个测验 (1:N)。 customers 表有 quiz_id 字段的原因是,在他创建的那些中,一次只能激活一个 (1:1)。
问题是当我尝试迁移时它崩溃了,因为两个表相互引用,通知我另一个表还不存在。
如果我将 CreateQuizzesTable 设置为先执行:
SQLSTATE[42P01]:未定义表:7 错误:关系不存在«客户»
如果我将 CreateCustomersTable 设置为先执行:
SQLSTATE[42P01]:未定义表:7 错误:关系不存在«测验»
我坚持,这不是 N:M 关系,我想避免使用中间表来管理它。
更新:查看@JasperStaats 的答案后,我仍然对表的播种有疑问。由于必须首先执行两个表播种器中的一个,因此它期望另一个表的外键值已经存在于数据库中(例如:如果我首先执行 QuizzesTableSeeder,它将无法插入值 'customer_id' = > 1,因为客户表仍然是空的。现在,我将该字段值保留为空,然后转到数据库并将其替换为适当的值,但这并不理想。
种子执行指令文件:
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(QuizzesTableSeeder::class);
$this->call(CustomersTableSeeder::class);
}
}
客户播种文件:
use Illuminate\Database\Seeder;
class CustomersTableSeeder extends Seeder
{
public function run()
{
\DB::table('customers')->delete();
\DB::table('customers')->insert(array(
0 =>
array(
'id' => 1,
'quiz_id' => 1,
'name' => 'user1',
'password' => 'pass1'
)
));
}
}
测验种子文件:
use Illuminate\Database\Seeder;
class QuizzesTableSeeder extends Seeder
{
public function run()
{
\DB::table('quizzes')->delete();
\DB::table('quizzes')->insert(array(
0 =>
array(
'id' => 1,
'customer_id' => 1,
'name' => 'quizz1',
)
));
}
}
【问题讨论】:
-
可能问题出在您的迁移文件序列中..
-
您可以制定的解决方案是,首先创建没有该关系的表(或仅在有效时未签名),然后迁移以将该密钥签名到另一个表。从来没有遇到过这个问题,所以我不知道这是否是最好的解决方案。
-
可能您需要创建第一个客户表,然后只有您可以在测验表中引用它。所以只需尝试先创建客户表,然后创建测验表。
-
@sandy 我已经在我的问题中解释了执行/创建的顺序并不重要,因为两个表都使用 FK 相互引用