Windows10に開発環境

Laravelは簡単に論理削除を実装できるのですが、意外と落とし穴が多くハマったところがあったので、列挙していきます。
よりスマートな回避方法があれば、突っ込んでください。

論理削除したのにuniqueのバリデーションが通らない

論理削除の場合、以下のようなバリデーションは削除済を含めて一意であることをバリデーションします。

    public function rules()
    {
        return [
            'name' => 'required|unique:countries'
        ];
    }

対策

1. uniqueのルールをカスタマイズする

    public function rules()
    {
        return [
            'name' => [
                'required',
                Rule::unique('countries')->whereNull('deleted_at')
            ]
        ];
    }

2. カスタムバリデーションでEloquent ORMを使う

Laravel5でカスタムバリデーションを参考にするとできる。今はめんどくさいけど、Laravel 5.5. Custom Validator Rulesによると、5.5で楽になりそう

また、existsについても同じように、「削除したのにバリデーションが通ってしまう」現象が起きるので、同様の処置が必要です。

Delete on Cascadeで孫が消えてくれない

Country < User < Postのリレーションを例に使います。

まず、Userのdeletingイベントはこんな感じで書けると思います。

    protected static function boot()
    {
        parent::boot();
        self::deleting(function ($user) {
           $user->posts()->delete();
        });
    }

Countryのdeletingイベントをこう書くとCountry削除時にPostは消えません。あら悲しい。

    protected static function boot()
    {
        parent::boot();
        self::deleting(function ($user) {
           $user->posts()->delete();
        });
    }

対策

1. さくっとぐるぐる削除

一番てっとり早いものの、できれば採用したくないやり方。
Userをひとつひとつ削除するので、Userモデルに書いたdeletingが発火してくれる。

    protected static function boot()
    {
        parent::boot();
        self::deleting(function ($country) {
            $users = $country->users;

            foreach($users as $user) {
                $user->delete();
            }

        });

    }

2. 削除するモデルを列挙

数が少ないならいいけど、リレーションしまっくてると書き出すのがめんどくさい

    protected static function boot()
    {
        parent::boot();
        self::deleting(function ($country) {
            $user_ids = $country->users->pluck('id')->toArray();

            Post::whereIn('user_id', $user_ids)->delete();
            User::destroy($user_ids);
        });
    }

検証用につくったリポジトリ

Contribute to softdelete-traps development by creating an account on GitHub.
[紹介元] PHPタグが付けられた新着投稿 – Qiita Windows10に開発環境

関連記事