Reputation: 3577
I have a parent model which must never exist without at least one associated hasMany relation. I am attempting to write validation for the model to ensure this never happens.
public static function boot()
{
parent::boot();
// reject model with no children
if (count($workflow->children) === 0) {
throw new RuntimeException("need at least one child");
}
});
}
But now I have a chicken and egg problem. I can't write the child record without the parent id. And I can't write the parent record until the save validation passes. But when I try to associate the children and call ->push() on the parent model, I get various issues depending on how I try to associate the two.
The following causes a FK constraint failure on the child column which references the parent:
$parent->children->add($child);
$child->parent()->associate($parent);
$parent->push();
Is Laravel just too stupid to handle this (seemingly reasonable) use case?
Upvotes: 2
Views: 3369
Reputation: 29268
Use Laravel's DB::beginTransaction()
, DB::commit()
and DB::rollback()
functions to prevent any stray information getting saved to the database. Take the following rough example:
public function save(){
DB::beginTransaction();
try {
$parent = new Parent();
$parent->save();
$child = new Child();
$parent->children()->save($child);
DB::commit();
} catch(Exception $e()) {
Log::error($e->getMessage());
DB::rollback();
}
}
Basically, using a try { ... } catch() { ... }
block with DB::beginTransaction()
, DB::commit()
and DB::rollback()
, you can try saving something to the database, and if no exceptions are caught, DB::commit()
the changes. If something goes horribly, terribly wrong, and exception will be caught, the error message will be logged and the changes will be discarded using DB::rollback()
.
Hope that helps!
Upvotes: 3