【Laravel】 リレーション先の複数テーブルのデータを論理削除する

# はじめに

リレーション先のテーブルデータを削除したい〜っていうのちょいちょいあって、
以下の記事とか参考にやっていたのですが、リレーション先テーブルが複数あってなんでかうまく行かないと、色々試行錯誤したときのメモ。

https://yaba-blog.com/larave-soft-delete/

Laravel親あれば結論からで。

# 結論

以下のwhere->delete()ではなく

```php
self::where('id', $id)->delete();
```

以下のように、find()->delete()することによって、bootが走るので

```php
self::find($id)->delete();
```

bootが走るとか、whereだとなぜダメかは以下より。

参考： https://readouble.com/laravel/6.x/ja/eloquent.html

# 内容

## ◇ 前提

```
- jsからpostでdelete処理を実行するイメージ
- 「Userテーブル」と「Postテーブル」、「Notificationテーブル」があると仮定
- 「Userテーブル」と「Postテーブル」は、「Userテーブル」の主キーと「Postテーブル」のカラムキーが同じものがあり、
「Userテーブル」と「Notificationテーブル」は、「Userテーブル」の主キーではなく他のカラムキーと「Notificationテーブル」のカラムキーを比較する
- 上記に対応するPHPファイルは既にある前提
- authは、おまけー
- コントローラーとかは省略
```

処理のjsからルーティング、モデルでたどっていけば処理が実行される。

## 処理


ひとまず着火するjs。
phpファイル内部にscript入れている感じ。


```js:app.php

<script>
const onPressDelete = (params) => {
  axios.post(params)
  .then((res) => {
    alert('削除に成功しました。');
  })
  .catch((err) => {
    alert('削除に失敗しました。');
  });
}
</script>

<div>
  // $deleteParamに「/test/delete」を入れておいている前提
  // 「jetstream」とかのレイアウトで変数渡し合いする時など
  <button type="button" onclick="onPressDelete('<?php echo $deleteParam; ?>')">
</div>
```

ルーティング

```php:route.php

<?php

  use Illuminate\Support\Facades\Route;
  use App\Http\Controllers\Admin\DeleteController;

  Route::group([
    'middleware' => 'auth:web'
  ], function () {
    Route::group([
        'prefix' => '/test',
        'as' => 'test.',
    ], function () {
        // 適当に削除処理のルーティング設定
        // コントローラーに渡して、サービスとかモデルに渡して実行させる
        Route::post('/delete', [DeleteController::class, 'delete'])->name('delete');
    });
  });
```



リレーション元の「Userテーブル」のPHPより

```php:User.php
<?php
  
  use Illuminate\Database\Eloquent\SoftDeletes;
  use Illuminate\Support\Facades\DB;
  use Illuminate\Database\Eloquent\Test;

  class User extends Test {
    // 論理削除設定
    use SoftDeletes;

    protected $fillable = [
        'hoge_id',
    ];

    // Postテーブルとのリレーション
    public function post(){
        return $this->hasMany(Post::class);
    }
    // Notificationテーブルとのリレーション
    public function notification($key){
        return $key ? $this->hasMany(Notification::class, $key) : $this->hasMany(Notification::class);
    }

    public static function boot(){
        parent::boot();
        
        // リレーション先のテーブルデータ削除
        static::deleted(function ($entry) {    
            $entry->post()->delete();
            // hoge_idをキーとして削除しにいく
            $entry->notification('hoge_id')->delete();
        });
    }

    public function delete(){
        DB::beginTransaction();
        try {
            self::find($id)->delete();
            DB::commit();
        } catch (Throwable $e) {
            DB::rollBack();
            throw $e;
        }
    }
  }
```

次に、リレーション先のテーブルたちのPHPは以下より

「Postテーブル」

```php:Post.php
<?php

  use Illuminate\Database\Eloquent\Test;
  use Illuminate\Database\Eloquent\SoftDeletes;

  class Post extends Test{
　　　　　　　　// 論理削除設定
    use SoftDeletes;

    public function entry()
    {
        return $this->belongsTo(User::class);
    }
  }
```

「Notificationテーブル」

```php:Notification.php
<?php

  use Illuminate\Database\Eloquent\Test;
  use Illuminate\Database\Eloquent\SoftDeletes;

  class Notification extends Test{
　　　　　　　　// 論理削除設定
    use SoftDeletes;

    protected $fillable = [
      'hoge_id',
    ];

    public function entry()
    {
        return $this->belongsTo(User::class);
    }
  }
```

# 所感

boot起動条件は把握していたが、複数テーブルでかつ、一つのテーブルだけ対象とするカラムキーが異なる場合に対応するときに、ちょい戸惑ったので、自分用メモということで書き溜め。
シンプルになっていなかったのは、自分の頭だった。


# 余談

以下とか困っている人はなかなかいたんだなーと。
ありがとうございます。参考にさせて頂いていました。

https://qiita.com/sawadashota/items/2cefb140441e1e720fc5
https://qiita.com/naoqoo2/items/2280bb94bdc6c97f58c4