Reputation: 73
Is this even possible? In every tutorial that I read there is nothing about deleting, only selecting and inserting related models.
This is my problem:
I have three levels of nesting. I have classes Package, Level, Lesson and Phase, and their models are below. First one - packages:
class Package extends Eloquent {
protected $table = 'packages';
public $timestamps = false;
public function levels(){
return $this->hasMany('Level', 'package_id');
}
}
Levels:
class Level extends Eloquent {
protected $table = 'levels';
public function lessons(){
return $this->hasMany('Lesson', 'level_id');
}
public function package(){
return $this->belongsTo('Package', 'package_id');
}
}
Lessons:
class Lesson extends Eloquent {
protected $table = 'lessons';
public function phases(){
return $this->hasMany('Phase', 'lesson_id');
}
public function level(){
return $this->belongsTo('Level', 'level_id');
}
}
What I'm trying to do here is to when deleting one package i delete all levels related to it and also to delete all lessons related to those levels.
I have tried couple of options and they were all wrong, I just don't know how to do this without making a bunch of queries in foreach loop. Please, give some advice I'm so desperate I'm thinking about tweet to Jeffrey Way and ask him for the solution :) Thanks in advance
Upvotes: 7
Views: 16220
Reputation: 1583
You can approach this in two ways:
Leverage the database to do the deleting for you. You'd add something like this to your migrations for the lessons
, levels
and packages
, respectively:
$table->foreign('level_id')->references('id')->on('levels')->onDelete('cascade');
$table->foreign('lesson_id')->references('id')->on('lessons')->onDelete('cascade');
$table->foreign('package_id')->references('id')->on('packages')->onDelete('cascade');
You can overwrite the delete
method on each model to delete all of its relationships:
class Lesson extends Eloquent {
protected $table = 'lessons';
public function phases(){
return $this->hasMany('Phase', 'lesson_id');
}
public function level(){
return $this->belongsTo('Level', 'level_id');
}
public function delete()
{
DB::transaction(function()
{
$this->level()->delete();
$this->phases()->delete();
parent::delete();
});
}
}
Upvotes: 8
Reputation: 1364
I think you can use foreign keys
with drop cascade
in your case. I haven't worked with Laravel's ORM yet, but there is a section in documentation that describes how to create foreign keys in migration.
Or you can try the technique suggested in this answer. The idea is to override the delete
method and force the deletion of related objects.
Upvotes: 0