I am developing an app in which you can create events and add posts to them. I have two Tables called events and posts. The events table has a preview_image column. The posts table has a picture column and a foreignId event_id.
Schema::create('events', function (Blueprint $table) {
$table->id('id');
// ...
$table->string('preview_image')->nullable();
// ...
});
Schema::create('posts', function (Blueprint $table) {
$table->id('id');
// ...
$table->string('picture');
$table->foreignId('event_id')->constrained()->cascadeOnDelete();
// ...
});
An example for an entry in both colums looks like this
Post
picture: "posts/2Ddh4wiTrBGBWQkRhQbTUTFGdVCFoW3KzvIhpfKW.png"
Event
preview_image: "events/lOzjzjSZul4tGULxzxfIxzfJGBlohe9np6NLazjA.jpg"
In my Event model I am overwriting the boot method to create a deleting function to delete the preview_image
protected static function boot()
{
parent::boot();
static::deleting(function($event) {
$picture = $event->preview_image;
if ($picture) {
$picturePath = storage_path('app/public/' . $picture);
if (file_exists($picturePath)) {
unlink($picturePath);
}
}
});
}
When I delete an Event all relating posts and the preview_image gets deleted.
Now I want the picture of every post to be deleted when the Post is deleted. So I did the same thing to my Post model.
protected static function boot()
{
parent::boot();
static::deleting(function ($post) {
$picture = $post->picture;
if ($picture) {
$picturePath = storage_path('app/public/' . $picture);
if (file_exists($picturePath)) {
unlink($picturePath);
}
}
});
}
My file structure:
app
public
events
event1.png
posts
post1.png
This is the function I am calling to delete the Event
public function deleteEvent($id)
{
$event = Event::findOrFail($id);
$event->delete();
return response()->json($event);
}
For some reason the picture of the post does not get deleted.
Does the deleting function not get called if the posts are removed by cascadeOnDelete()? If so how can I call the deleting function while deleting each post. Or is there another method to delete relating files with cascadeOnDelete().
laravel version: v9.24.0
CodePudding user response:
A cascading delete happens at the database level. There are no Eloquent events fired.
If you need Eloquent events to fire on the deleted child records, you'll need to ditch cascadeOnDelete, and implement the deletion cascade yourself via a deleted event on the parent model.
CodePudding user response:
cascading delete does not execute the deleting function in my Post model.
Like ceejayoz said:
A cascading delete happens at the database level. There are no Eloquent events fired.
I solved this problem by calling the delete function of each post before deleting the event.
public function deleteEvent($id)
{
$event = Event::findOrFail($id);
$posts = $event->posts;
foreach ($posts as $post){
$post->delete();
}
$event->delete();
return response()->json($event);
}
now cascadeOnDelete is unnecessary and I can remove it
