83
61

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Laravel】フォームリクエストを使いつつ勝手にリダイレクトさせない

Last updated at Posted at 2019-01-15

フォームリクエストバリデーションを使うと簡単にバリデータを書けて楽ではあるのですが、こいつはバリデーションに失敗すると勝手に前ページにリダイレクトします。
リダイレクト先を変更する手段はありますが、止める手段がありません。
リダイレクトさせずにコントローラ側でどうこうしたいことがあったのだけど、その対応にやたら苦労したので備忘録。
試したバージョンはLaravel5.7。

ソース

フォームリクエスト

<?php
namespace App\Http\Requests;

use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;

class FooRequest extends FormRequest
{

    /**
     * バリデーションルール
     *
     * @return array
     */
    public function rules()
    {
        return [
            'bar' => 'required',
        ];
    }

    /**
     * @Override
     * 勝手にリダイレクトさせない
     * @param  \Illuminate\Contracts\Validation\Validator  $validator
     */
    protected function failedValidation(Validator $validator)
    {
    }

    /**
     * バリデータを取得する
     * @return  \Illuminate\Contracts\Validation\Validator  $validator
     */
    public function getValidator()
    {
        return $this->validator;
    }
}

リクエスト時にはまずValidatesWhenResolvedTrait::validateResolved()が呼ばれるのだが、その中でif ($instance->fails()) { $this->failedValidation($instance); }までべったり書かれている。
そしてFormRequest::failedValidation()はその中でリダイレクトしている。

ここまでコントローラより先に動くので、コントローラからは手を出す手段がない。
従って、フォームリクエストでfailedValidation()を上書きしてリダイレクトしないようにした。

次にコントローラからバリデータを取得したいのだが、フォームリクエストのValidatorはprotectedであり、さらに取得するメソッドがないのでコントローラで取り出すことができない。
従って、Validatorを取得するメソッドgetValidator()を追加した。

コントローラ


class FooController extends Controller
{
    /**
     * なんかするアクション
     * @param FooRequest
     * @return Response
     */
    public function setBar(FooRequest $request)
    {
        // バリデータ取得
        $validator = $request->getValidator();
        // 以後Validatorファサードと同じように使える
        if($validator->fails()){
            return redirect('hoge/fuga')
                ->withErrors($validator)
                ->withInput();
    }
}

Validator::makeしたときと同様にValidatorを取れるので、あとはコントローラ側で任意に操作することができる。

感想

解決策だけ見ると簡単っぽく見えるけど、当初は流儀に則ったやり方がないかを探していたらFormRequestやらValidatesWhenResolvedTraitやらValidation\Factoryやらを延々彷徨う羽目になりました。
そのうえ良さげな方法が結局見当たらなかったので、直接上書きして穴を空けるという物理的解決法になりました。
絶対もっといい方法があると思うんだけどどうなんだろう。

その他

Laravelは用意された道に沿って歩くだけなら快適だけど、ちょっとでも道を外れようとすると途端に酷道になるという印象。

今度はRoute::any('hoge\{fuga}', 'HogeController@{fuga}Action');ってできないのか調査中。

83
61
3

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
83
61

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?