Mastering Form Validation in Laravel 5

Laravel developers have always had a nice validation class out of the box, but unfortunately we have never had a standard way of using it. Some people prefer doing validation in controllers, others do it in models and I, as many others, preferred to do it in a separate validation layer. Of course, all of these methods worked for us, but having a best practice is always preferred.

In this article we’ll review the new feature of Laravel 5 which gives us a great standard way of doing validation and several other things.

Form requests

Everytime we send a form to a server, we do a HTTP request. Form requests are dedicated classes which handle and represent these requests in Laravel 5 applications.

To see a typical form request class, we can generate it like follows:

php artisan make:request CreateUserRequest

This command generates a CreateUserRequest class in the app/Http/Requests directory. Let’s see what it looks like:

As you see, by default it consists of two public methods: rules and authorize.

Validation

You probably suspect that the rules method is responsible for validation and, of course, you are right.

This method is expected to return a regular set of Laravel validation rules we are familiar with:

Nothing new here. That’s good but how do we use this class?

To demonstrate it, let’s generate a simple Users controller:

php artisan make:controller UsersController

I’ve removed everything except two relevant store and update methods:

And the most awesome part starts here. To use the form request, you have to think back the previous article about method injection in Laravel 5. Just inject the form request into a relevant method (store method in our case) and you’re done:

Now you’re probably a little bit confused or don’t get what’s going on. The code snippet above is everything you have to do to validate your request. Let me explain in the next section.

Validation in depth

What makes it possible to keep the controller method free of all conditional statements and explicit calls to a form request instance?

The magic is in the way Laravel handles the request. There is a listener in the FormRequestServiceProvider which does validation *before* we hit the controller.

The implementation details are not so important but it is very important to understand that the application will *never* hit the controller method if validation fails.

Fine, but what happens in that case? By default, Laravel redirects the request back to the failed form with populated $errors variable (instance of familiar MessageBag).

Of course, we can change this behavior. There are many ways to do this but to keep the article short we’ll review the easiest one. To change the redirect URL, you just have to set a $redirect property of your CreateUserRequest class:

Now, if validation fails, the request will be redirected to users/create URI.

To get better idea of how this works and how to customize it, please see the response and getRedirectUrl methods of the FormRequest class in the Laravel repository: [FormRequest.php](https://github.com/laravel/framework/blob/master/src/Illuminate/Foundation/Http/FormRequest.php).

Conclusion

From my point of view, form requests are one of the best new features of Laravel 5. A few benefits of using this approach:

  • It gives us a standard way of validating our requests
  • As rules is a method, you can put a custom logic in there (for example, you don’t have to hard code a table name as we did in the reviewed example)
  • You have a nice object-oriented way of organizing your validations. In some cases we have different validation rules for store and update methods and having a separate form request is the best way of solving this problem. As a “home assignment”, try to create an UpdateUserRequest which makes password field optional but when it’s filled out, it has to match the password_confirmation field.

This topic is too wide for a single article. That’s why I decided to write another article where we’ll review autorization and several other benefits of the awesome form requests. Stay tuned!

  • http://notflip.be/ Miguel Stevens

    How would you redirect with input? This doesn’t seem to be a standard feature

    • Chetan

      $errors variable is always available to use, if there will be any error. The array would fill up

      Now in your views,
      @if(count($errors))
      …..
      @endif

  • mark gxr

    awesome but i have found in a simple way like laravel 4 just need some upgrade in our controller and done found here a simple way http://tutsnare.com/laravel-5-form-validation/

  • nardev

    At the end of an article called “Mastering Form Validation in Laravel 5” you wrote “This topic is too wide for a single article.” … so.. it’s not mastering at all…

  • http://tinyurl.com/ziishaned Zeeshan Ahmed

    Good article (Y)