Laravel 5.5 - Validate Multiple Form Request - at the same time

末鹿安然 提交于 2019-12-08 03:32:26

A FormRequest throws an Illuminate\Validation\ValidationException Exception when validation fails which has a redirectTo method, and from there the Exception Handler performs the redirect.

You can achieve your desired behaviour by running your Form Requests manually in your controller within a try/catch block which captures the errors and combines the error bags before redirecting, or if it's essential that you run them by Laravel injecting them into your controller then you would need to add your own exception handler which captures all of the errors, combines them and then redirects after the final Form Request has ran.

However, it's worth noting, both of those approaches aren't great: they're cumbersome and are going to cause you more problems than they solve. You should try to adhere to the Laravel way of doing things as best possible if you'd like to write a maintainable application.

A Form Request exists to validate a form, therefore, each Form should have one Form Request, if you wish to compose a Form Request from different sets of rules then that should be done within the Form Request, e.g:

  1. Define your Form Request for your form php artisan make:request StoreMultipleForm
  2. From the rules method on StoreMultipleForm fetch the rules for each of the other Form Requests and then return them together, e.g:

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        $formRequests = [
          TransportationRequest::class,
          PurchaseRequest::class,
          SaleRequest::class
        ];
    
        $rules = [];
    
        foreach ($formRequests as $source) {
          $rules = array_merge(
            $rules,
            (new $source)->rules()
          );
        }
    
        return $rules;
    }
    
  3. Use the new composed Form Request in your controller, e.g:

    public function store(StoreMultipleForm $request)
    {
        // Do actions here.
    }
    

The advantages of this method are that it's self-contained, it adheres to the one form one Form Request expectation, it doesn't require changes to the Form Requests you're combining and if you need to add additional rules unique to this form you can do so without creating another Form Request.

If I understand correctly, you have 3 forms, each with their own form requests to deal with their respective validation. You also have another form which combines those 3 forms somewhere else and you don't want to repeat yourself by rewriting those validation rules.

In which case, I would still suggest going with a single form request, but try to combine the rules of each of those individual requests. For example, you use static methods to define your rules on the 3 individual form requests and have each individual request call its own static method to grab them:

class TransportationRequest extends FormRequest
{
    public static function getRules()
    {
        return []; // Return rules for this request
    }

    public function rules()
    {
        return static::getRules();
    }
}

class PurchaseRequest extends FormRequest
{
    public static function getRules()
    {
        return []; // Return rules for this request
    }

    public function rules()
    {
        return static::getRules();
    }
}

class SaleRequest extends FormRequest
{
    public static function getRules()
    {
        return []; // Return rules for this request
    }

    public function rules()
    {
        return static::getRules();
    }
}

And then have your combined request merge all three sets:

class CombinedRequest extends FormRequest
{
    public function rules()
    {
        return array_merge(
            TransportationRequest::getRules(),
            SaleRequest::getRules(),
            PurchaseRequest::getRules()
        );
    }
}

Then you can use the single CombinedRequest in your controller method. Of course, if you don't like the static method approach, in your combined request rules method you could just new up each individual request and call the rules method on each of them and merge the results.

class CombinedRequest extends FormRequest
{
    public function rules()
    {
        $transportation = (new TransportationRequest())->rules();
        $sale = (new SaleRequest())->rules();
        $purchase = (new PurchaseRequest())->rules();

        return array_merge(
            $transportation,
            $sales,
            $purchase
        );
    }
}

I would create traits containing the rules for each FormRequest - purchase, transporataion and sale. Use the trait in it's specific FormRequest and then when you need all the rules you can use all three traits in the combined FormRequest and merge the rules arrays then.

You could concatinate all rules and validate manually:

$allRules = (new TransportationRequest)->rules() + (new PurchaseRequest)->rules() + (new SaleRequest)->rules();
Validator::make($request->all(), $allRules)->validate();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!