Mohamed Benhida

admin@devma.net

December 29, 2017

TIP - Delete Cascade On Laravel

We all find this error when we want to delete a row in table and we we get an error Constraint ID ... something related to realtionships in database that we have the existing ID already used on other table.

in this post we will talk on how can we prevent this error in laravel so stay tunned. we will work on an example of each Post has many comments.

we create the comment table then we add the relation on Post Model

php artisan make:model Comment -m

comment Migration

I made content_id and content_type so we can distinct the comment of wish table Post or Something else that require comments ...

 Schema::create('comments', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user_id');
            $table->unsignedInteger('content_id');
            $table->string('content_type');
            $table->timestamps();
        });

App\Post.php

morphMany is like hasMany but with type and id 

 public function comments()
    {
        return $this->morphMany('App\Comment','content');
    }

App\Comment.php

public function content()
    {
        return $this->morphTo();
    }

Now we will create a test to see if we can create a comment

/** @test */
    public function it_can_create_a_comment()
    {
        $user = factory(\App\User::class)->create();
        $this->actingAs($user); //Sign In $user

        $post = factory(\App\Post::class)->create(); //Create a Post

        $comment = $post->comments()->create(['user_id' => auth()->user()->id]);
        //Create a comment

        $this->assertEquals($comment->content->title, $post->title);
    }

if we launch the test we will get a green bar if we do all right.

Here come what we looking for in each laravel model have a static method named boot is a function that trigger every time we call this model like __construct.

we have also a deleting event that it trigger each time we deleting a post.

this event accept closure like parametre so in this closure we will delete all the comments related to this current post deleted like this,by doing that we get rid of the database error.

App\Post.php

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

        static::deleting(function($post) {
            $post->comments()->delete();
        });
    }

Now we make a test to see if it is worked

/** @test */
    public function it_can_delete_a_post()
    {
        $user = factory(\App\User::class)->create();
        $this->actingAs($user); //Sign In $user

        $post = factory(\App\Post::class)->create();

        $post->comments()->create(['user_id' => auth()->user()->id]);
        $post->comments()->create(['user_id' => auth()->user()->id]);

        $post->delete();

        $this->assertEquals(0,$post->comments()->count());
    }

if we follow all the steps the test should pass.

this post can helps you.

© Mohamed Benhida.

Blog | Packages | About