Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel delete all belongsToMany relations in belongsToMany relation

I have a Tournament model which contains a belongsToMany relationship with a Session model:

class Tournament extends Model{

    public function sessions(){
        return $this->belongsToMany(Session::class, 'tournament_has_sessions');
    }
}

Then my sessions model contains a belongsToMany relationship with the User model:

class Session extends Model{

    public function users(){
        return $this->belongsToMany(User::class, 'session_has_users');
    }

}

Now when I delete a Tournament, I want to delete all sessions and all information in the session_has_users table with it.

I have tried:

$tournament->sessions()->with('users')->delete(); -- < This
$tournament->sessions()->delete();
$tournament->users()->detach();
$tournament->delete();

But it does't work. The data in the session_has_users table persists

I realize i could do something like this:

DB::table('session_has_users')->whereIn('session_id', $this->sessions()->pluck('id'))->delete();

But is there a more efficient/handy (or even alternative if not more efficient) way to accomplish this?

like image 368
Joas Avatar asked Dec 05 '17 17:12

Joas


2 Answers

Using RDBMS Referential Actions on the Foreign Key

In the database schema, you should define the foreign key with the ON DELETE CASCADE action. This will automatically delete the related records when the referenced id is deleted.

(See dbudimir's answer for the example lines from a Laravel migration file)


Using Eloquent to Detach All Related Models

If you aren't using foreign keys or your database lacks the support for referential actions, you can use this:

$tourament->sessions()->sync([]);

The sync method accepts an array of IDs to place on the intermediate table. Any IDs that are not in the given array will be removed from the intermediate table. So, after this operation is complete, only the IDs in the given array will exist in the intermediate table:

https://laravel.com/docs/5.5/eloquent-relationships#updating-many-to-many-relationships

Providing an empty array should then remove all the relations.

like image 126
Devon Avatar answered Oct 26 '22 23:10

Devon


In the table 'tournament_has_sessions' you can set onDelete('cascade') like this

$table->integer('tournament_id')->unsigned()->nullable();
$table->foreign('tournament_id')->references('id')->on('tournaments')->onDelete('cascade');    
$table->integer('session_id')->unsigned()->nullable();
$table->foreign('session_id')->references('id')->on('sessions')->onDelete('cascade');

And when delete tournaments automaticly deleted all records in this table

like image 23
dbudimir Avatar answered Oct 26 '22 23:10

dbudimir