Laravel Handle Deleting Of One to Many Relationship Example : Deleting Category, One Category has many posts

In this tutorial let’s dig into how we can gracefully delete data that belongs to one to many relationship in Laravel.

For this let’s consider an example of a relationship between Category and Post. Category can have many posts.

If you delete the category without handling the associated posts then it will cause problems in the application, since you have post data in your database which is still associated with a category that does not exist.

In this solution, once we delete the category, we will assign the associated posts to an Uncategorized category.

Livewire Component Library

Here is how Category Model looks like

Host Laravel Application on DigitalOcean

Use coupon 5balloons on this Cloudways Affiliate URL to get special discount.
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{

    protected $guarded = [];

    public function posts(){
        return $this->hasMany('App\Post');
    }

}

Here is how the destroy method of CategoryController is

public function destroy(Category $category)
{
   $category->delete();

   return redirect('/admin/categories')->with('success', 'Category Deleted !');
}

Now before deleting the Category, we want to assign the associated posts to an Uncategorized Category.

Create a boot method in your Category model with below code.

public static function boot() {
        parent::boot();

        static::deleting(function($category) { // before delete() method call this
            $uncategorized = Category::firstOrCreate(['name' => 'Uncategorized', 'slug' => 
                             'uncategorized', 'description' => 'uncategorized']);
            Post::where('category_id', $category->id)->update(
                             ['category_id' => $uncategorized->id]);
        });
}

We are executing our custom code on deleting event of the Category model. This code will be executed just before the delete action is called on Category model.

In the code we get the id of Category with name ‘Uncategorized’, if the category does not exist in the database then we create it by using firstOrCreate eloquent method.

After that, we assign the Post which belongs to the Category being deleted to UnCategorized category.

That’s It. Here is a Feature test to go along with this feature.

/** @test */
public function when_category_deleted_associated_post_assigned_to_uncategorized_category(){
    //Given that we have a signed in user
    $this->actingAs($this->user);
    //And given that we have a category
    $category = factory('App\Category')->create();
    //And a post associated with the category
    $post = factory('App\Post')->create(['category_id' => $category->id]);

    //When we delete the category the post should be assigned to uncategorized category
    $this->delete("/categories/{$category->id}");
            
    $category_id = Category::where('name', 'Uncategorized')->first()->id;

    $post = $post->fresh();

    $this->assertEquals($category_id, $post->category_id);

}

Site Footer