我已经建立了以下雄辩的模型和关系:
申请人
class Applicant {
public function application()
{
return $this->hasOne(Application::class);
}
}
应用
class Application {
public function applicant()
{
return $this->belongsTo(Applicant::class);
}
protected $fillable = [
// ... other fields
'applicant_id',
];
}
及其迁移:
applicants
桌子
public function up()
{
Schema::create('applicants', function (Blueprint $table) {
$table->increments('id');
// other fields ...
});
}
applications
桌子
public function up()
{
Schema::create('applications', function (Blueprint $table) {
$table->increments('id');
// other fields ...
$table->integer('applicant_id')->unsigned();
// other relations ...
$table->foreign('applicant_id')->references('id')->on('applications')->onDelete('cascade');
});
}
我只想创建一个新申请人,然后为刚刚创建的申请人添加一个新申请:
$applicant = Applicant::create([
// data
]);
$application = $applicant->applications()->create([
// data
]);
但是,运行此代码时,我收到以下错误:
SQLSTATE[23000]: Integrity constraint violation:
1452 Cannot add or update a child row: a foreign key constraint fails (
`dbname`.`applications`, CONSTRAINT `applications_applicant_id_foreign`
FOREIGN KEY (`applicant_id`) REFERENCES `applications` (`id`) ON DELETE CASCADE
)
(SQL: insert into `applications` (
`status`,
`reference_number`,
`organisation_id`,
`qualification_id`,
`applicant_id`,
`updated_at`,
`created_at`
) values (
pending,
573066CE59BFE,
24,
1,
12, // <------ applicant_id, i.e. the foreign key!
2016-05-09 11:30:38,
2016-05-09 11:30:38
))
据我了解,发生错误是因为我正在向它传递数据库中不存在的外键。因此,我想知道在第一次创建申请人的数据库调用时这里发生了什么:
$applicant = Applicant::create([
// data
]);
是否在创建应用程序的第二条语句之前未将其写入数据库:
$application = $applicant->application()->create([
// data
]);
...并因此导致违反完整性约束?因为如果我dd($applicant)
在创建dd(Applicant::find($applicant->id))
记录后立即获得记录,也可以在数据库中查看它。
我发现在重构代码时,当我调用create()
添加一条新记录然后逐行并使用创建一个新的应用程序时save()
,我没有遇到这个问题。因此,我很想知道这两个调用之间有什么不同(如果有的话)以及处理这种情况的正确方法是什么,因为我认为这是我之前做过很多次的口才非常简单的事情。任何建议将不胜感激,谢谢!
编辑1
更正了联系关系:
$applicant->application()->create(...)
不是:
$applicant->applications()->create(...)
编辑2
运行此代码:
$applicant = Applicant::create($this->applicantDataFromRequest($request));
$application = new Application([
'status' => 'pending',
'reference_number' => $request->get('passport_number'),
'organisation_id' => $request->get('organisation'),
'qualification_id' => $request->get('qualification') ?: null,
]);
$applicant->application()->save($application);
dd('done');
并收到相同的错误(已更新为页面上的所有错误):
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`dbname`.`applications`, CONSTRAINT `applications_applicant_id_foreign` FOREIGN KEY (`applicant_id`) REFERENCES `applications` (`id`) ON DELETE CASCADE) (SQL: insert into `applications` (`status`, `reference_number`, `organisation_id`, `qualification_id`, `applicant_id`, `updated_at`, `created_at`) values (pending, 5730970933C7B, 24, 1, 22, 2016-05-09 14:56:25, 2016-05-09 14:56:25))
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`dbname`.`applications`, CONSTRAINT `applications_applicant_id_foreign` FOREIGN KEY (`applicant_id`) REFERENCES `applications` (`id`) ON DELETE CASCADE)
编辑3添加了相关的迁移
更新1
真奇怪!在开始重构代码之前,我已经通过git恢复到该项目的较早版本,该版本在该版本中可以正常工作,但由于相同的原因,它无法正常工作!不知道这是怎么回事!?
更新2
刚刚注意到迁移过程中确实有些愚蠢的事情:
applications
桌子
public function up()
{
Schema::create('applications', function (Blueprint $table) {
$table->increments('id');
// other fields ...
$table->integer('applicant_id')->unsigned();
// other relations ...
$table->foreign('applicant_id')->references('id')->on('applications')->onDelete('cascade');
});
}
外键应为:
$table->foreign('applicant_id')
->references('id')
->on('applicants')
->onDelete('cascade'); // not applications!
这里有两点:
为什么这直到现在都没有影响我的代码?直到现在很奇怪为止,它一直运行良好。
要更新外键约束并尝试一下,看看现在是否可以使用
在迁移过程中,外键约束引用了错误的外表(实际上是在引用自身),这是一个愚蠢的错误!
create_applications_table
迁移的错误代码:
$table->foreign('applicant_id')
->references('id')
->on('applications') // wrong table
->onDelete('cascade');
正确的代码:
$table->foreign('applicant_id')
->references('id')
->on('applicants') // correct table
->onDelete('cascade');
现在可以正常工作:
$applicant = Applicant::create([
// data
]);
$application = $applicant->applications()->create([
// data
]);
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句