Laravel validation – use multiple Form requests for complex scenarios

Not a long time ago I’ve already written about different ways of data validation in Laravel applications. Today I would like to show how you could use multiple Form requests classes when you handle more complex scenario.

Let’s assume we have website where we allow to create multiple types of user. For example we might have regular users, sellers and partners. Let’s assume some parts of registration are quite common and we want to handle registration in single controller method.  Each type of user has of course different registration fields. Let’s asume that:

  • regular users have only email and password fields
  • sellers have company, email and password fields
  • partners have partner_number and password fields

Of course in real world scenario there would be much more fields than those but that number is quite enough just to present the idea.

Single Form request class validation

Because we assumed we need to use single controller method, we should also have single Form request class to handle the validation. Let’s see how this method could look like:

First of all, notice that we assumed we have addtional type field. It’s quite reasonable to have type field sent based on chosen user type during registration.

But as you see, this class is already quite long and remember we used here very low number of fields. What if we offer more than 3 types of users? As you see it would get a bit complicated and this switch would get much more complex.

Of course, we could still improve it, extracting rules for different types of user to additional methods but it would still mean that we would have quite long Form Request class.

And how we could use this form request class in our controller? Well, we just inject this like this:

Multiple Form request validation classes

What if we could extract validation rules of each user type into separate class? This would make our classes much shorter and we would have validation for each user type in separate class. So what do we need?

First of all, we should make sure we have type field. This is special field and we are going to use custom Form request classes based on this field, so let’s start with simple Form request that will handle validation of this single field:

As you see, it’s very simple, and we would just use this in our controller method like this:

The problem is that we cannot inject further Form request classes into our method conditionally, so we should somehow create them into controller method. The key here is to understand how Form validation request classes are handled. Each Form request class implements  Illuminate\Contracts\Validation\ValidatesWhenResolved interface and it makes that whenever Form request object is created then automatically validation is made. So in fact if we would like to, we could even run validation like this:

The effect would be exactly the same. So how we could use this now? Well, we could resolve request class based on parameter type we have like this:

Having code like this first RegisterTypeRequest class validation would be run and in case if validation passes (we have valid type field value) then validation for specific type of user would be run. The last step is creating Form requests for each user type.

For regular users validation would look like this:

For sellers it would look like this:

And finally for partners it would look like this:

As you see, it’s pretty clean now. For each user type we have now really clean validation class and we don’t need now any additional switches.

Summary

In this article I showed you how you can use multiple Form requests in case you want (or need) to handle multiple cases validation for single controller method. I hope you enjoyed it and now you really think using Form request is much better than using validation directly in controller

2 Comments

  1. Arek

    Genialne ! 😀 szukałem czegoś podobnego do obsługi różnego typu danych, która przyjmuje jedna metoda w zależności od warunku określonego przy wywołaniu. Proste, a jakie genialne. Dziękuję ! :))

Leave a Reply

Your email address will not be published. Required fields are marked *

*