Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jrean's avatar

On Delete Cascade

Hi,

I have a Venue and Event table. A Venue can have many Event(s). An Event belongs to many Venue(s). ... I have a pivot table venues_events

The migration is as follow:

            $table->increments('id');
            $table->integer('venue_id')->unsigned();
            $table->integer('event_id')->unsigned();

            $table
                ->foreign('venue_id')
                ->references('id')
                ->on('venues')
                ->onDelete('cascade');

            $table
                ->foreign('event_id')
                ->references('id')
                ->on('event')
                ->onDelete('cascade');

            $table->timestamps();

For now I'm working with an sqlite database and I think I will stick with this solution because the project is very small...

My very first question is how to achieve a cascade delete on the pivot table when I delete an event or a venue? When I perform $item->delete() it won't cascade.

I googled (I'm not sure) but it seems sqlite doesn't manage very well cascading... (Correct me if I'm wrong).

I continued googling and found eloquent events results... Because I'm running with Laravel 5.1 I think the eloquent events term is not anymore appropriate (correct me if I'm wrong).

Instead I think I can use Laravel events /listenners. Is this the right way? Is there some other technics? Should I use detach() before deleting my item? Please share the best practice for a simple situation like mine.

Thank you :)

0 likes
5 replies
pmall's avatar

I continued googling and found eloquent events results... Because I'm running with Laravel 5 I think the eloquent events term is not anymore appropriate (correct me if I'm wrong).

You can use model observers for this.

class Venue extends Eloquent
{
    public static boot function ()
    {
        self::deleting(function ($venue) {

            // This will be executed right before the venue is deleted
            // Put your delete related model logic here

        });
    }
}

Also be careful, if you do the cascade on the venue side and on the event side, it could enter an infinite loop...

1 like
vitr's avatar

@jrean , the best practice is not to delete at all))) just mark your records as deleted and keep them, let's say, for history.
The cascading solves the problem of orphaned records, with this approach you will never have such orphaned records.
Later on you can clean up your database (actually delete records marked before and sub-records related to them ) by some background process during off-peak hours.
cheers

3 likes
jrean's avatar

@pmall @vitr Thank you.

So, to summarise,

  • When I have many to many relations with pivot tables I need to take care of "orphaned" records.
  • When deleting one or both parent(s) members of a pivot table, Laravel doesn't bring "out of the box" a solution tied to the delete() method. Right?
  • I put ->onDelete('cascade'); on both members within my pivot table migration. Is that wrong?
  • One solution could be to detach() relation(s) before deleting inside the destroy() method (of a resource controller for instance). Right?
  • Another solution could be to extract the logic outside the controller method inside the Eloquent model using model observer. Right?
  • Then I could consider not deleting at all the records but instead marking them as deleted with the soft delete solution (I still need to ding into it). But, with that last solution, how does it work with pivot table? I mean, even if one or both parent(s) are (soft)deleted, I can't keep relation records inside the pivot table... The first exemple coming to me is inside a Venue show vue, I will display related/attached event(s). If relation(s) are still existing within the pivot table... I will have issue...

Can you both please try to help me a little bit more (again).

Thank you :)

pmall's avatar

I mean, even if one or both parent(s) are (soft)deleted, I can't keep relation records inside the pivot table...

You don't care, they are soft deleted, they won't be selected by any query.

You can soft delete a venue and its events then you don't care what is in the pivot table.

If you don't soft delete them, some pivot table record will be orphan. It is not a problem, just a matter of taste.

1 like
polyphem's avatar
    /**
     * The "booting" method of the model.
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        static::deleting(function($model)
        {
            if ($model->forceDeleting) {
                $model->roles()->detach();
            }
        });
    }

use $model->forceDeleting :)

Please or to participate in this conversation.