やりたいこと

Laravel くんで Controller をすっきりさせたいので、バリデーションをフォームリクエストで行いたい。
プラスで、簡単な条件分岐のバリデーションも付け足したい。

結論

withValodatorメソッドを通してsometimesを使うのが良さげです。

詳しく

通常のフォームリクエストでのバリデーション

    // FormRequest
    namespace App\Http\Request;

    use \\illuminate\Foundation\Http\FormRequest;

    class ItemUpdateRequest extends FormRequest
    {
        /**
          * Determine if the user is authorized to make this request.
          *
          * @return bool
          */
        public function authorize()
        {
            return true;
        }

        public function rules()
        {
            return [
                'id' => 'required|integer',
                'item_type' => 'required|string|in:tv,web,radio'
                'name' => 'required|string|max:255',
                'url' => 'nullable|url|max:2083,
                'note' => 'nullable|string|max:2047',
            ];
        }
    }


    // Controller(必要な記述以外は省略)
    use App\Http\Request\ItemUpdateRequest;

    class ItemController extends Controller
    {
        public function update(ItemUpdateRequest $request)
        {
            //
        }
    }

これだけで通常のバリデーションは出来ますね。
ただ、例えばitem_type == 'web'の時だけurlカラムは必須にしたいとか、そういった簡単な条件付けは rules の中ではできません。

条件付きのバリデーションの追加

じゃあどうするよ。前述の通り、withValidatorメソッドとsometimesを使います。
メソッドについては、以下にそれらしいことが書いてあります。

Laravel Validation

sometimes は条件ごとに適応するルールを記載できるものなので、それを使用してフォームリクエストに下記メソッドを追加するだけ。

    /**
      * Configure the validator instance.
      *
      * @param \Illuminate\Validation\Validator $validator
      * @return void
      */
    public function withValidator($validator)
    {
        $validator->sometimes('url', 'required', function ($input) {
            return $input['item_type'] == 'web';
        });
    }

このフォームリクエストを継承して作る子クラスにもこのメソッド内の条件は引き継がれます。
この記述だと条件一つに対して一文が長くなってしまうので、条件分岐が多い/複雑な場合には向かないかもですが、ちょっとした分岐が必要な際には活用できると思います。