0

This question is based on this thread: Merge 2 rules FormFequest for validate an update and store action in laravel5.5

Context: Let's suppose I have these 2 requests and I want to merge the SocialMediaFormRequest rules in ReadersFormRequest rules.

ReadersFormRequest

class ReadersFormRequest extends FormRequest
{
    public function rules(SocialMediaFormRequest $social)
    { 
        $mediaRules = $social->rules();
        $rules = [
            'first_name'=>'required',
            'last_name'=>'required',
            'birthday'=>'required',
            'region'=>'required',
            'photo_url'=>'required',
            'support'=>'required',
            'riwayas_id'=>'required',
            'description'=>'required',
        ];
        return array_merge($rules,$mediaRules);
    }
}

SocialMediaFormRequest

class SocialMediaFormRequest extends FormRequest
{

    public function rules()
    {
        return [
            'url'=>'required|url',
            'title'=>'required'
        ];
    }
}

Form that I received

first_name: "example"
last_name: "example"
birthday: 2022-06-13
region: somewhere
photo_url: "https:XXX"
support: false
riwayas_id: 1
description: ""
media.url: "https:YYY"
media.title: "stackoverflow"

Question: How can I only pass the argument media.XXX in my form SocialMediaFormRequest?

1 Answers1

0

You can use prepareForValidation() method in the form request to sanitize the inputs : https://laravel.com/docs/9.x/validation#preparing-input-for-validation

So, if in SocialMediaFormRequest you receive the full request you can only get the required fields like that:

    public function prepareForValidation()
    {
        $this->replace([
            'url' => $this->url ?? ($this->media['url'] ?? null),
            'title' => $this->title ?? ($this->media['title'] ?? null),
        ]);
    }

Also, in ReadersFormRequest when you inject the other request or resolve it from the container it doesn't work correctly, so it is better to get the rules like that:

public function rules()
{ 
     $mediaRules = (new SocialMediaFormRequest())->rules();

and in order to access the media.* attributes in ReadersFormRequest you can again use prepareForValidation:

public function prepareForValidation()
{
    $this->merge([
        'url' => $this->media['url'] ?? null,
        'title' => $this->media['title'] ?? null,
    ]);
}
RossTsachev
  • 921
  • 1
  • 7
  • 19
  • If you mean that prepareForValidation() should go in my **ReadersFormRequest**, that's not a good idea, because SocialMediaFormRequest will receive some value (like first_name, last_name, birthday, etc) that it should not receive. If you mean that prepareForValidation() should go in my **SocialMediaFormRequest**, then what would happen when I use another form that directly contain "url, title"? Since we use merge, it should change nothing, but I ask just to be sure. Also, SocialMediaFormRequest will still receive value from ReadersFormRequest and it should not receive them. – jeremie bergeron Jun 14 '22 at 11:39
  • @jeremiebergeron - edited my answer with the considerations from your comment – RossTsachev Jun 14 '22 at 14:38
  • Thank you! However, **$mediaRules = (new SocialMediaFormRequest())->rules();** seems to not initialized the request correctly, because when I debug it, I can see that it has no parameter (it should have url and title). But, if I keep what I already wrote in my ReadersFormRequest, it work without any problem. – jeremie bergeron Jun 14 '22 at 15:13
  • The idea is that all the validations happen inside the ReadersFormRequest, from SocialMediaFormRequest you only get the rules and add them in the current request. As I tested if you inject the request and you have failed validations from both rulesets, only the media.* will be displayed in your form. Of course, if you have additional logic in your SocialMediaFormRequest, leave it as it is, just keep it mind that behavior. – RossTsachev Jun 14 '22 at 16:21
  • *The idea is that all the validations happen inside the ReadersFormRequest, from SocialMediaFormRequest you only get the rules and add them in the current request.* I am totally agree with you, but if I wrote **$mediaRules = (new SocialMediaFormRequest())->rules();**, I can see with the debugger that my SocialMediaFormRequest instance has no parameter, so it always that it missed some fields. – jeremie bergeron Jun 14 '22 at 17:18