Search code examples
phplaravelsoft-delete

Soft Delete Cascading with Laravel 5.2


I'm trying to implement soft deleting in Laravel.

Here are my relationships

Tournament ( hasMany ) CategoryTournament (hasOne) CategorySettings
Tournament ( hasMany ) CategoryTournament (belongsToMany) CategoryTournamentUser

So, I used this answer that help me a lot

Now, when I SoftDelete a Tournament, all CategoryTournaments related are also deleted.

But then, I tried to apply it recursively, so I wrote the same code in CategoryTournament Model:

static::deleting(function($categoryTournament) {
        $categoryTournament->settings()->delete();
        $categoryTournament->users()->delete();
    });

But this code is never ran. I checked that I have settings and user to delete, but none of them are soft deleted...

Did I miss something??? It should work!

EDIT:

Now, I am trying to Soft Delete a User, it is just one more level:

User (HasMany) Tournament ( hasMany ) CategoryTournament (hasOne) CategorySettings

So now, when I soft Delete user, it delete his tournaments, but it doesn't delete anymore his CategoryTournaments, so this is not a config error.


Solution

  • Inside your static boot method you have to iterate through your toMany relations.

    F.a:

    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Database\Eloquent\SoftDeletes;
    
    class Tournament extends Model
    {
      use SoftDeletes;
    
      public function categoryTournament() {
        return $this->hasMany(CategoryTournament::class);
      }
    
      protected static function boot() {
        parent::boot();
    
        static::deleting(function($tournament) {
          foreach ($tournament->categoryTournament()->get() as $ct) {
            $ct->delete();
          }
        });
      }
    }
    

    The other files should look like this:

    CategoryTournament.php

    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Database\Eloquent\SoftDeletes;
    
    class CategoryTournament extends Model
    {
      use SoftDeletes;
    
      public function tournament() {
        return $this->belongsTo(Tournament::class);
      }
    
      public function settings() {
        return $this->belongsTo(Settings::class);
      }
    
      protected static function boot() {
        parent::boot();
    
        static::deleting(function($categoryTournament) {
          var_dump('categoryTournament');
          $categoryTournament->settings()->delete();
        });
      }
    }
    

    Settings.php

    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Database\Eloquent\SoftDeletes;
    
    class Settings extends Model
    {
        use SoftDeletes;
    
        public function categoryTournament() {
          return $this->hasOne(CategoryTournament::class);
        }
    
        protected static function boot() {
        parent::boot();
    
        static::deleting(function($settings) {
          var_dump('settings');
        });
      }
    }
    

    Migration

    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;
    
    class CreateTables extends Migration
    {
      /**
       * Run the migrations.
       *
       * @return void
       */
      public function up() {
    
        Schema::create('tournaments', function (Blueprint $table) {
          $table->increments('id');
          $table->timestamps();
          $table->softDeletes();
        });
    
        Schema::create('settings', function (Blueprint $table) {
          $table->increments('id');
          $table->timestamps();
          $table->softDeletes();
        });
    
        Schema::create('category_tournaments', function (Blueprint $table) {
          $table->increments('id');
          $table->integer('tournament_id')->unsigned();
          $table->integer('settings_id')->unsigned();
          $table->timestamps();
          $table->softDeletes();
    
          $table->foreign('tournament_id')->references('id')->on('tournaments');
          $table->foreign('settings_id')->references('id')->on('settings');
        });
      }
    
      /**
       * Reverse the migrations.
       *
       * @return void
       */
      public function down() {
    
        Schema::drop('category_tournaments');
        Schema::drop('settings');
        Schema::drop('tournaments');
      }
    }