Laravel Form Request: Store/Update - Same or Separate Class?

preview_player
Показать описание
Let's dive into some examples of how/when you would use the same or separate Form Request classes for validation. Spoiler alert: it's mostly a personal preference.

- - - - -
Support the channel by checking out our products:
Рекомендации по теме
Комментарии
Автор

I prefer the first approach (separate store and update, even if there's redundancy).

If you want to use a single request with unique validation, I think you can achieve this with the new null-safe operator introduced in php8 or with the optional() helper like so:

'email' => [ 'required', Rule::unique( 'users' )->ignore( optional( $this )->admin )) ]

intipontt
Автор

A) I don't think you understand what Single Responsibility means. It does not mean one method per class, lol. If that is the definition, then your controller is violating it too ;)
B) Removing the password field/property from the request defeats the whole point of using the 'sometimes' rule. Just don't use it, lol. If it's not 'required' (or 'sometimes') it can be present in the request, or not, or it can be present and set to null. This seems to be the functionality you're looking for on update. No extra/different rule necessary...unless I'm missing something.
C) You look like Sergio Perez's father! Awesome! He's my favorite Formula 1 driver.
D) Thanks for all the great videos!

wetbevryertyv
Автор

Trying to make it as efficient as possible (with multiple conditionals) is just making it harder and harder to read. Do this instead: define validation rule sets for each route that hits that validator. For each route define the route name as the key to which the values are the validation array you would put normally. Then, by using this in a look-up table manner, you can easily provide the validation rule set you need (by passing in route name as a key to the look-up table of rule sets).
Although there will be duplicates in rules, it does change 2 things - now the logic is more readable for multiple route support and rules are in one place, desatured of conditionals in order to make it as easily updateable as possible.

Guys, look-up tables are damn powerful. Use them. Or match expression, it's powerful also.

ward
Автор

Never call $this->admin->id, instead of that use $this->route('admin')->id, imagine you have input with the name "admin" then you have a problem.

michaloravec
Автор

I would have to disagree at 3:32 - The validation should just be validating the data not deciding what data to validate based on the name of a route. The validation class shouldn't be concerned with routes. Single Responsibility?

phpcoding
Автор

I prefer to use one request for store and update (It is easy if controllers are 10 or 20, but if they are 200?). In most cases. But, insteat of checking request()->routeIs(...) I'm using $this->route('user') !== null (if is used Route model binding). This prevent for errors if we change the route for some reason (even the route is changed, url must contain {user}). And I have custom stub for those kind of request, where just throw model in artisan command. And I think $this->route('admin') is little better than $this->admin :)

inso
Автор

Thanks. Is very interesting to compare so many options. I prefer one Class with optional field with the new when methode it is mutch more easy

GergelyCsermely
Автор

Separate validators for store and update. Then you can easily apply different permission checks; such as can create, but not update.

You could argue that you can use an if-statement here, but then you introduce more cognitive complexity, as developers have to understand the if-statement — for lesser experienced/junior developers this *could* be more tedious.

It's just more straightforward IMO to separate them, plus for the cases you mentioned about having different fields

KnightYoshi
Автор

I can use both, And I have used them in different project.

As I follow you and you are my idle. I want to know that which one you have used. I will use that.
Thank you sir😍

bmtamim
Автор

I mostly put all requests into the same class say UserRequest and have the logic base of the request method with a switch case which cases are request methods. this->method() would return the request type if you follow good standards like a post to create, put to update, etc. Delete and Update always return an empty array are grouped. Put and patch are also grouped as they perform almost the same thing.

Code below:

$rules = [];

switch($this->method()) {
case ‘GET’:
case ‘DELETE’: {
return $rules;
}
case ‘POST’: {
// rules here
}
case ‘PUT’:
case ‘PATCH’: {
// rules here
}

return $rules;
}

kwameadoko
Автор

For me, I prefer the use one class with a method switch inside rules method:
EX. switch ($this->method()) {
case 'POST':
{
return [
'password'' => ['required']
];
}
case 'PUT':
case 'PATCH':
{
return [
'password' => ['optional']
]
}
default: break;

alila
Автор

i make 2 request for update and store. Thanks for sharing 🙂.

gamerneversleep
Автор

Woow, i didn't know that we can access the controller's variables inside the form request, this piece of information is very useful, thank you💙

tarekalhalabi
Автор

Chief thank you for the dark theme as well.

johwel
Автор

Not sure if it's mentioned, but I think that with the classes that share the same implementation, it seems reasonable to use separate classes, but have them both subclass from a common parent class so as to cut down on the duplication.

OnlinePseudonym
Автор

I like the first example, but have one question
What about the next apis? How to create one request class for them:
POST /api/reservation/
{
reservation_id: string,
request params ....
}
and
PUT
{
request params ....
}

kostjantin
Автор

I prefer to use the last method, I mean, the same request for the two methods I think it's more simple! But every option is valid

Автор

I have recently used UserRegistration Request for the same and just use the same rules for register and update. I just used $request->except('password') to not include the password then check make it has and add $data['password'] = $hasedPassword. This way I have written more readable code and made it simple for onboarding other dev easy.

debjit
Автор

I create two classes, store and update. The update class extends the store class. This way the update class will be empty until the rules need to be different.

TobiasOlssonHovby
Автор

I personally like to use switch case on the basis of method for each different action.

ahmedrezwan