バリデーションの話です。バリデーションのルールには、implicitルールというのがあり、入力値の項目が存在しない、あるいは値が空のときに、実行されるルールです。

ルールと言えば、numericとかのように値があってのexplicitのルールが直感的ですが、値がないときのルールとは何でしょう?

ぱっと思いつかないかもしれませんが、頻繁に使うrequiredは、値がないときのimplicitルールです。必須なのだから、値がなくてもバリデーションを実行しなければなりません。

Implicitルールが必要なケースは意外にもあります。例えば、以下の管理画面における会員編集の画面。

ここでは、有効のチェックボックスがオン(有効)ですが、これをオフ(無効とする)として投稿するとチェックボックスの入力値はありません。しかし、例えば、会員を無効にするには、未支払いの注文があってはいけない、というルールがあるとすると、これはimplicitルールを作成しないとそのルールを強制することはできません。

このカスタムルールを作成してみましょう。

$ php artisan make:rule MemberDeactivateRule

作成されたファイルを編集します。

namespace App\Rules;

use App\Models\Member;

use Illuminate\Contracts\Validation\ImplicitRule;

class MemberDeactivateRule implements ImplicitRule
{
    protected $member;

    /**
     * Create a new rule instance.
     * @param  \App\Models\Member $member
     * @return void
     */
    public function __construct(Member $member)
    {
        $this->member = $member;
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        // チェックボックスをオンとすると、'Y'を返すとする。
        if ($value == 'Y') {
            return true;
        }

        // チェックボックスがオフなら、
        // 未払いの注文があるかどうかをチェックして、エラーとする
     if ($member->checkUnpaid()) {
            return false;
        }
        
        return true;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return '未払いの注文があります';
    }
}

通常のカスタムルールと違うのは、カスタムルールのクラスの実装にImplicitRuleのインターフェースを使用していることです、通常は、ImplicitRuleの代わりにRuleのクラスを使用します。

最後に、コントローラで、このカスタムルールを使用したバリデーションは、以下のようになります。

...
$request->validate(['active_flag' => new MemberDeactivateRule($member)]);

By khino