我已经建立了以下雄辩的模型和关系:
申请人
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!
这里有两点:
为什么这不会影响我的代码呢?它一直很好,直到现在很奇怪......
要更新外键约束并试用它以查看它是否正常工作
答案 0 :(得分:0)
试试这个:
$applicant = new Applicant([
// data
]);
$application = new Application([
// data
]);
$applicant->applications()->save($application);
答案 1 :(得分:0)
昨天使用create方法时遇到了完全相同的问题。尝试从1表单保存到两个模型并收到相同的完整性约束错误。
如果您正在使用create,则可以先实例化您的申请人:
$applicant = Applicant::create(//applicant data);
$application = new Application(//application data);
$applicant->application()->save($application);
答案 2 :(得分:0)
在迁移过程中,外键约束引用了错误的外表(它实际上是引用自身),这是一个愚蠢的错误!
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
]);