こんにちはーむちょこです。
Laravel 6.x系から、バリデーションに特定の条件下ではフィールドを除外するルール「exclude_if」「exclude_unless」が追加されました。
公式の説明がかなりあっさりしていたので、実例を添えてご紹介したいと思います!
公式説明
exclude_if:anotherfield,value
The field under validation will be excluded from the request data returned by the validate and validated methods if the anotherfield field is equal to value.
https://laravel.com/docs/6.x/validation#rule-exclude-if
exclude_if: 他のフィールド, 値
検証中のフィールドは、指定した他のフィールドの値が指定した値と等しい場合、validateメソッドとvalidatedメソッドによって返されるリクエストデータから除外されます。
exclude_unless:anotherfield,value
https://laravel.com/docs/6.x/validation#rule-exclude-unless
The field under validation will be excluded from the request data returned by the validate and validated methods unless anotherfield’s field is equal to value.
exclude_unless: 他フィールド, 値
検証中のフィールドは、指定した他フィールドの値が指定した値と等しくない場合、validateメソッドとvalidatedメソッドによって返されるリクエストデータから除外されます。
活用シーン
たとえばラジオボタンでリクエスト内容が切り替わるような場面で便利です。
例として、ペットの種類で犬を選択したときだけ必須項目が増えるフォームを作ってみました。
実装例
フォームのHTMLコードはこんな感じです。
<div class="field">
<label class="label">ペットの種類はなんですか?<span class="is-danger tag">必須</span></label>
<div class="control">
<label class="radio">
<input type="radio" name="animal" value="dog" required> 犬
</label>
<label class="radio">
<input type="radio" name="animal" value="cat" id="delegation"> 猫
</label>
</div>
</div>
<div class="field">
<label class="label">普段のフード名を教えてください<span class="is-danger tag">必須</span></label>
<div class="control">
<input
class="input " type="text" name="food" value="" required>
</div>
</div>
<div class="field for_dog">
<label class="label">ご希望のお散歩コースを教えてください<span class="is-danger tag">必須</span></label>
<p class="control">
<label class="checkbox">
<input type="checkbox" class="checkbox" name="course[]" value="park"> 公園コース
</label>
</p>
<p class="control">
<label class="checkbox">
<input type="checkbox" class="checkbox" name="course[]" value="river"> 川コース
</label>
</p>
<p class="control">
<label class="checkbox">
<input type="checkbox" class="checkbox" name="course[]" value="shortest"> 最短コース
</label>
</p>
</div>
まずRequestクラスを生成します。
$ php artisan make:request SampleRequest
Request created successfully.
生成されたRequestクラスのrules()メソッドを編集して、まずは選択の結果は関係なく、それぞれの項目のルールを定義しておきます。
use Illuminate\Validation\Rule;
public function rules()
{
return [
'animal' => [
'required',
Rule::in(['dog', 'cat'])
],
'food' => [
'required',
'max:255'
],
'course' => [
'required'
],
'course.*' => [
Rule::in(['park', 'river', 'shortest'])
]
];
}
定義したルールは以下のとおりです。
animal:必須、dogかcatのみを受け付ける
food:必須、255文字以内
course:必須、配列の値はpark, river, shortestのいずれかのみを受け付ける
次に、本題であるexclude_ifやexclude_unlessを使ってanimalの値がdogでないときはcourseを除外するルールを付け足してみます。
exclude_if
まずexclude_ifを使ったパターンです。
'course' => [
'exclude_if:animal,cat',
'required'
],
これでanimalの値がcatのときにcourseが除外されるようになります。
courseの値がなんであろうとvalidate()が通り、validated()の返り値からはcourse要素が消えます。
var_dump($request->validated());
array(2) {
["animal"]=>
string(3) "cat"
["food"]=>
string(3) "カナガン"
}
exclude_unless
今度はexclude_unlessを使って実装してみます。
'course' => [
'exclude_unless:animal,dog',
'required'
],
animalの値がdogでないときにcourseが除外されるようになりました。
一見exclude_ifと全く同じ条件で実装されているように見えますが、exclude_unlessの場合はanimalの値が空のときもcourseが除外されることにご注意ください。
以上、exclude_ifとexclude_unlessの使い方のご紹介でした!