I've got the following eloquent models and relations set up:
Applicant
class Applicant {
public function application()
{
return $this->hasOne(Application::class);
}
}
Application
class Application {
public function applicant()
{
return $this->belongsTo(Applicant::class);
}
protected $fillable = [
// ... other fields
'applicant_id',
];
}
And their migrations:
applicants
table
public function up()
{
Schema::create('applicants', function (Blueprint $table) {
$table->increments('id');
// other fields ...
});
}
applications
table
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');
});
}
I simply want to create a new applicant then add a new application for the applicant just created:
$applicant = Applicant::create([
// data
]);
$application = $applicant->applications()->create([
// data
]);
However, when running this code I receive the following error:
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
))
As I understand, the error is occuring because I'm passing it a foreign key that doesn't exist in the database. So I was wondering what is happening here with the first call to the DB that I make to create the applicant:
$applicant = Applicant::create([
// data
]);
Is it not written to the DB before the second statement that creates the application:
$application = $applicant->application()->create([
// data
]);
... and thus causing the integrity constraint violation? Because if I dd($applicant)
immediately after creating it or dd(Applicant::find($applicant->id))
I get the record and I can also view it in the DB.
I've found that prior to re-factoring my code when I was calling create()
to add a new record then building up a new application line by line and using save()
, I didn't encounter this issue. So I'm curious to know how both calls differ (if they do) and what would be the correct way to approach such a scenario as I thought it was something very simple with eloquent which I've done many times before. Any advice would be most appreciated, thanks!
Edit 1
Corrected call to relation:
$applicant->application()->create(...)
not:
$applicant->applications()->create(...)
Edit 2
Running this code:
$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');
And receiving the same error (updated with all errors on page):
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)
Edit 3 Added relevant migrations
Update 1
Really strange! I've reverted back to an older version of the project via git where it was working before I began re-factoring my code and now that's not working for the same reason! No clue what's going on here!?
Update 2
Just noticed something really silly in the migrations:
applications
table
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');
});
}
The foreign key should be:
$table->foreign('applicant_id')
->references('id')
->on('applicants')
->onDelete('cascade'); // not applications!
Two points here:
Why did this not effect my code til now? It's been working fine til now weird...
Going to update the foreign key constraint and try it out to see if it works now
Within the migrations the foreign key constraint was referencing the wrong foreign table (it was actually referencing itself), a silly mistake!
The erroneous code for the create_applications_table
migration:
$table->foreign('applicant_id')
->references('id')
->on('applications') // wrong table
->onDelete('cascade');
The correct code:
$table->foreign('applicant_id')
->references('id')
->on('applicants') // correct table
->onDelete('cascade');
This now works just fine:
$applicant = Applicant::create([
// data
]);
$application = $applicant->applications()->create([
// data
]);
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments