How to merge two Request in Laravel

2019-07-09 00:26发布

问题:

In my Laravel (5.1) project I need to create a Request for validating a form.

But for this request, i would like to merge two different requests :

The first request :

class AdvertisementRequest extends Request {

    public function authorize()
    {

        return true;
    }

    public function rules()
    {
        return [
            'ads_type' => 'required|numeric|in:0,1',
            'category' => 'required|numeric|exists:categories,id',
            'title' => 'required|alpha_num|max:45',
            'description' => 'required|alpha_num|max:2000',
            'price' => 'required|numeric',
        ];
    }

}

The second request :

class UserRegisterRequest extends Request {

    public function authorize()
    {

        return true;
    }

    public function rules()
    {
        $rules = [
            'form_type' => 'required|numeric|in:0,1',
            'user_type' => 'required|numeric|in:0,1',
            'phone' => 'required|phone_number',
            'region' => 'required|numeric|exists:regions,id',
            'department' => 'required|numeric|exists:departments,code',
            'postal_code' => 'required|postal_code',
            'city' => 'alpha|max:45',
            'id_city' => 'required|numeric|exists:cities,id',
            'last_name' => 'required|alpha_sp|max:45',
            'first_name' => 'required|alpha_sp|max:45',
            'pseudo' => 'required|alpha|max:45|unique:users',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|alpha_num|min:6|max:45',
        ];

        return $rules;
    }
}

And i would like to create a third request which combining the two other like that :

class UserAdvertisementRegisterRequest extends Request {

    public function authorize()
    {

        return true;
    }

    public function rules()
    {
        $rules = [
            'ads_type' => 'required|numeric|in:0,1',
            'category' => 'required|numeric|exists:categories,id',
            'title' => 'required|alpha_num|max:45',
            'description' => 'required|alpha_num|max:2000',
            'price' => 'required|numeric',

            'form_type' => 'required|numeric|in:0,1',
            'user_type' => 'required|numeric|in:0,1',
            'phone' => 'required|phone_number',
            'region' => 'required|numeric|exists:regions,id',
            'department' => 'required|numeric|exists:departments,code',
            'postal_code' => 'required|postal_code',
            'city' => 'alpha|max:45',
            'id_city' => 'required|numeric|exists:cities,id',
            'last_name' => 'required|alpha_sp|max:45',
            'first_name' => 'required|alpha_sp|max:45',
            'pseudo' => 'required|alpha|max:45|unique:users',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|alpha_num|min:6|max:45',
        ];

        return $rules;
    }
}

Is there any solution for do that without duplicate my code ?

Sorry for my bad english :/.

Thank you in advance for you reply !

回答1:

The simplest way would be to generate the merged list of validation rules in your UserAdvertisementRegisterRequest::rules method in the following manner:

class UserAdvertisementRegisterRequest extends Request { 
  public function rules()
  {
    return array_merge(
      with(new AdvertisementRequest)->rules(), 
      with(new UserRegisterRequest)->rules()
    );
  }
}


回答2:

I was trying to be smart about a merge by extending another request and trying to combine the rules with logic between the parent / child requests. I also had different rules / format for GET vs POST, so my parent request class had a function that would hand me the data based on that, which one of my transformers was expecting.

But ultimately it's better to keep things decoupled, and I found that it is possible to inject multiple request objects into the controller. Each request will contain the same values, but each will have validated the request according to their own rules. For my transformer, I only pass the version of the request that the transformer is expecting so it can call the extended get function and transform from there.

public function store(
    StoreEventRequest          $storeEventRequest, 
    UserListRequest            $userListRequest, 
    UserListRequestTransformer $transformer
) {
    $eventDetails     = $storeEventRequest->all();
    $userListIterator = $transformer->requestToUserList($userListRequest);
    ...
}