0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Laravel】FormRequestクラスのワイルドカード・カスタムバリデーション・prepareForValidation()について

0
Posted at

概要

実務で、理解に苦しんだ表題にある3つの機能について、自分の備忘録用にまとめる。

・ワイルドカードの使い方
・カスタムバリデーションの仕組み
・prepareForValidation()の使い方

ワイルドカードについて

普段、よく使うバリデーションルールは以下のようにBladeで定義されたname属性をキー名に設定しています。

簡単なバリデーション
public function rules(): array
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required|string',
    ];
}

ですが、name属性やインプットされたデータが配列の場合、上述した書き方ではバリデーションが設定できない。
そんな時に役に立つのが、ワイルドカードです。

配列が単一の場合: 配列名.*

インプットされたデータが以下のような単一の配列だった場合は「.*」を使う。

data[0], data[1]...

単一の配列の場合
'data.*' => 'required|max:12' 

このように記述することで、各配列の要素にルールを設定することができる。

連想配列の場合: 配列名 .*. キー名

インプットされたデータが連想配列で以下のような形式の場合は「.*.」を使う。
ソースコード参考:https://qiita.com/sakuraya/items/abca057a424fa9b5a187

連想配列の場合
user = [
    [0] = [
        'username' => 'foo',
        'email' => 'foo',
        'password' => 'foo'
    ],
    [1] = [
        'username' => 'bar',
        'email' => 'bar',
        'password' => 'bar'
    ],
    [2] = [
        'username' => 'fizz',
        'email' => 'fizz',
        'password' => 'fizz'
    ]
]   

Requestクラスでは以下のように、ルールを設定する。

FormRequestクラス
public function rules()
{
    return [
        'user.*.username' => 'required|max:12' 
        'user.*.email' => 'required|email|max:100' 
        'user.*.password' => 'required|min:8|confirmed' 

    ]
}

カスタムバリデーションについて

Laravelにはバリデーションルールが多く用意されているが、複雑なルールやプロジェクト特有のルールを適応させたい場合に役立つのが、カスタムバリデーションです。

以下のコマンドでRuleオブジェクトを作成します。

php artisan make;rule クラス名

コマンドを打つと以下のディレクトリにファイルが作成されます。
app/Http/Rules

作成されたファイルのvalidate()、もしくはpasses()にロジックを記述することでカスタムバリデーションとして、任意のルールを設定することができます。

カスタムバリデーションの使用

FormRequestクラスでは以下のように定義します。

FormRequestクラス
///
public function rules(): array
{
    return [
        'status' => [
            'required',
            // newでインスタンス化して定義する
            new CheckStatus()
        ],
        'date' => 'required'
    ]
}

Ruleクラスは以下。

CheckStatus.php
///
public function validate(string $attribute, mixed $value, Closure $fail)
{
    // ここにロジックを記述する
}

string $attribute とは

このパラメータには、バリデーション対象のname属性が入ります。
もし、エラーメッセージをカスタムしたい場合はこの値を使用することでメッセージにバリデーション対象の名前を含めることができます。

mixed $value とは

このパラメータには、ユーザーが実際に入力した値が入ります。

Closure $fail とは

このパラメータには、バリデーション失敗を報告するための関数が入ります。
例えば、入力値が「completeでなければならない」というルールの場合は以下のようになります。

///
public function validate(string $attribute, mixed $value, Closure $fail)
{
    // $attributeは'status'
    // $valueはstandbyの場合

    if ($value !== 'complete')
        fail (":attribute が正しくありません。")
}

対象の属性以外をRuleクラスで使用する場合

カスタムバリデーションを使用する際、対象の属性以外をRuleクラスで使用するには2通りのやり方が存在する。

①new クラス名 (ここに渡す)

1つ目は、newでRuleクラスをインスタンス化する際、引数にそのクラス内で使いたい属性を入れる方法です。

public function rules(): array
{
    return [
        'status' => [
            'required',
            // 'date'を使いたい場合
            new CheckStatus(
                $this->input('date')
            )
        ],
        'date' => 'required'
    ]
}

②Ruleクラス側でrequestを使って値を取得する

2つ目は、Ruleクラス側でrequestを使って値を取得する方法です。
Controller側でBladeのname属性を取得するやり方と同様に記述することで取得が可能です。

prepareForValidation()について

prepareForValidation()とは、FormRequestクラスでバリデーションルールによるチェックを行う前の値に手を加えることができる機能です。
具体的には以下のように使用します。

protected function prepareForValidation()
{
    // ここでは、sales = 100,000 を 100000 に変換している
    $this->merge([
        'sales' => str_replace(',', '', $this->sales)
    ]);
}

終わりに

この記事では、表題の3つの機能についてまとめてみました。
どの機能も最初は取っ付きにくく、分かりずらかったですが調べて使っていくうちに非常に便利な機能であるとに気づきました。

至らぬ点がありましたら、ご共有いただけますと幸いです。

以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?