Laravel Validation で、2つの項目の内どちらか1つは必須。でも2つ共の入力はダメ、を実現してみる。
前置き
という事で、タイトルに書いたバリデーションの内容を見て行きたいと思います。
どなたかの名言を借りて表現すれば、「俺か、俺以外か。」のバリデーションって事ですね。
本題
さて、それでは次のようなシチュエーションを考えてみたいと思います。
名前かニックネームか、どちらか片方は必須で、両方共に入力してはいけないという状況です。 (やや非現実的なサンプルですが、そこは気にしないでください)
結論から言ってしまうと、Laravel Ver.9.49 以降であれば、以下のように書くことができます。
public function rules(): array
{
return [
'name' => ['required_without:nickname', 'nullable', 'string', 'max:100'],
'nickname' => ['prohibits:name', 'nullable', 'string', 'max:100'],
];
}
public function messages(): array
{
return [
'name.required_without' => '名前かニックネームは、どちらかは必須です。',
'nickname.prohibits' => '名前かニックネーム、どちらかだけを入力して下さい。',
];
}
required_without:nickname
は、ニックネームに入力が無ければ、名前は必須。
prohibits:name
では、ニックネームに入力があれば、名前の入力を禁じるというルールです。
これでひとまずオッケーですね。
という事で以上ではあるのですが、ここで終わるのであれば、わざわざブログ記事にもせず、Twitter で呟いて終わっていた所ですが、例によって少し続きがあります 🍺
続き
prohibits
は、Laravel Ver.8.58 から存在しているのですが、Laravel 9.49 未満の場合は、上記は期待した動作にはならないかも知れません。
そもそも prohibit 系のルールには、他にも prohibited
, prohibited_if
, prohibited_unless
などがあるのですが、何気に Laravel 9.49 で挙動が整理されました。
それ未満の場合、'prohibits:name' とした場合、空であるのはもちろん、名前欄が存在する事自体がNGになります。要は、もっと厳しいんですね。
ですが、Laravel 9.49 では、厳しい版の missing 系のルールが登場したので、prohibit 系は、ちょっと緩い系に統一されることになったんですね。
詳しくは、下記などをご覧下さい。
上記は、Laravel 10 からの変更では無く Laravel 9.49 からの変更です。Laravel 9.49 って、Laravel 10 のリリースも近い頃なんですが、そこを敢えてマイナーリリースでやっちゃう所が、 Laravel 的ですね😎
それではまた。
Discussion