一般社団法人 全国個人事業主支援協会

COLUMN コラム

  • Laravelのフォームリクエストでソフトデリートを採用しているテーブルを扱う時の注意点

Laravelのバリデーションで’unique’を利用しているシステムは多いと思います。これにより重複したデータを弾くバリデーションを組むことができます。

そして論理削除(ソフトデリート)について。これはデータの削除を行う際にレコードを消すのではなく、フラグ(deleted_atなど)を用意してアプリケーション上は消したよう振る舞うものです。

 

今回は、上記のuniqueバリデーションと論理削除で少しハマった話です。

例としてvideosテーブルには論理削除を採用しています。そしてvideos.titleカラムにはuniqueバリデーションルールを適用しています。

しかしこの状態では、「論理削除済みのvideosのtitle」すらも再度登録ができません。

ユーザーからしたら「登録していないのに『既にデータがあります』ってエラー出る、なんだこれ使えね」となります。これが今回の問題です。

 

長くなりましたが、以下の通りuniqueのバリデーションを修正して対応しました。クエリビルダを使ってuniqueの条件をカスタマイズすることが可能です。

'title' => [
    'required',
    'max:400',
    $this->rule
        ->unique($this->video->getTable())
        // ソフトデリートされていないレコードが対象
        ->where(fn (Builder $query) => $query->whereNull('deleted_at')),
],

 

コメントの通りwhere句を追加し、deleted_atがnull(未削除のデータ)をuniqueの対象としました。

ただし最後に、videos.titleにunique制約張っている場合はもちろんクエリ実行時にコケます。

なので論理削除を採用する場合は対策なしだとunique制約と競合するのでご注意を。

 

▼参考(‘追加のWHERE節を付け加える’より)

https://readouble.com/laravel/10.x/ja/validation.html#rule-unique

The following two tabs change content below.

小林 聡太

Webエンジニアしてます。2020年に独立しました。 技術的なことから個人事業主として必要なことまで色々お話しします。

この記事をシェアする

  • Twitterでシェア
  • Facebookでシェア
  • LINEでシェア