|

Laravel Validation

Laravel Validation

In our last episode when we worked with the Laravel Form Class, we were able to add some great functionality to our small RESTful blog application. We saw how the Laravel Form Class made it easy to bring forth forms with great power and efficiency. We also used the great Twitter Bootstrap Framework to spice up the looks just a little bit. There is something we need to add though to the forms we have created and that would be Validation. Validation is super important for any web based application. It is certainly not good to let users submit blank information, or worse, malicious information into our web forms. By using validation, we can overcome this nuisance. Let’s jump into Laravel Validation!


Before the current glory days of working with Laravel, web builders would need to string together complex collections of regular expressions in the form of either client side javascript, server side PHP, or a combination of both. Frankly, I’ve always found the task of having to create all this validation repetitive and a bit dull. So instead of doing things the old way and getting our brains wracked up over dealing with the ever cryptic regular expressions, we can simply implement the Laravel Validation Class and get rocking and rolling with solid validation in no time.


Laravel Validation In Controller

We can start by validating in the store method of the BlogpostsController. Let’s whip up some validation using the easy Laravel syntax of Facade::verb, in this case Validator::make

What we do here is pass in an array, and each key of the array maps to a field in the database. The corresponding value for each key refers to some type of validation. There are many rules you can use here. In our case we are just going to use required but if we wanted to we could use any of the following available rules to validate the type and value of the data to be inserted into the given field in the database: Required With, Image (File), Required Without, After (Date), Integer, Size, Regular Expression, Date, Digits, Alpha, Active URL, Required If, MIME Types, Different, URL, IP Address, Date Format, E-Mail, Between, Required With All, Numeric, Before (Date), Unique (Database), Required, In, Same, Alpha Numeric, Alpha Dash, Digits Between, Exists (Database), Max, Required Without All, Confirmed, Min, Not In, and Accepted.

When we create an instance of the Validation class by using Validator::make, we now have access to two methods which are oh so appropriately named fails() and passes(). We can use these methods to carry out the validation. So let’s do something super easy at first.

We’ll add this to our BlogpostsController before we create a new instance of a Blogpost.

Now, if we try to submit the form without entering any data, the browser will return, ‘Oh No You Dont!’

Ok, this is pretty weak. Instead of sending back that message and simply leave the user wondering what to do next, we should redirect the user back to the form, re populate the form with any data she submitted, and flash some error messages to the screen that would be helpful to her. How do we do this? We do this like so:

Redirect::back() sends the user back, withInput() repopulates the form, and withErrors() captures the error messages, just make sure to pass in $validation->messages() for it to actually work.

Great! Now in the view, we need to specify a place to echo out the errors to the screen. Since we have Twitter Bootstrap by way of cdn in our master layout file, we’ll bootstrapify our error messages here so the user is well aware of the troubles they are having. Our create.blade.php file will now look like this:

So now if we go ahead and navigate to http://you.rock/blogposts/create and then hit the Create Post button without actually entering any information into our Title Field or Body Field, the user will see this friendly screen:

laravel form validation

That looks great, it is working as designed. We didn’t fill out the Title or Body field so we get the message that both The title field is required and The body field is required. Let’s now change it up a bit. We’re going to fill out the body field, but in our absentmindedness will forget to fill out the title field. We will then hit Create Post and see what our current validation rules do for us.

laravel form validation no title

This is fantastic! Laravel intelligently deals with this and alerts the user that The title field is required but at the same time, repopulates the form so that the user does not have to painfully retype all of the text back in. Amazingly, we still see a lot of websites, some from big brand name companies, that can’t do simple form validation right. Sure, they’ll alert if you something went wrong, but that novel length message you just wrote into their message submit form is Poof!, Gone, Zip, Zilch, Nada, Bye Bye. There is nothing more annoying than forms that do not repopulate correctly.


Laravel Validation In Model

In the prior section we got our validation up and running pretty easily. We simply instantiated an instance of the validator class in the store() method of the BlogpostController, and as you can see, everything seems to work quite well. That method is a great way to get things up and running quickly when you’re not worried about the best design pattern. Once you get things working, it might make sense to extract the validation logic to the Model. Let’s see how we might accomplish this.

Define Rules in the Model

The first step is to move the rules from the BlogpostsController to the Blogpost Model. Instead of removing the code entirely, we’ll just comment it out so we can easily see the difference.

Controller

Model

Now we have moved the validation rules over to the Model and everything still works the same as before.

Create a static method in the model to validate

We could also clean up the controller by moving the logic into a static method defined in the model, then just call that method from the controller, let’s see that now:

Model

Controller

Now this is pretty slick. We have moved most of the logic over to the model, and just use a couple simple lines of code in the store() method of the controller to complete the validation, and everything works like a champ. One small drawback is that we did make use of static methods and properties in order to do so. This goes against the overlords of the PHP society, so we will need to fix that.


Laravel Validation via Dependency Injection

As it stands now, validation is working just fine using the code above. It could be made better and cleaner however by using dependency injection. First though, what is dependency injection and why use it? Dependency injection is a way to eliminate hard coded dependencies and provide the ability for easier testing and the ability to swap implementations. It is a means to inject the needed object into the current one. Dependency Injection can become a bit tricky if you are manually instantiating and passing in dependencies, but thankfully the Laravel IoC Container takes care of the heavy lifting for us.

Currently in the store() method of the BlogpostsController we directly reference the Blogpost Model via static methods and properties as shown here:

We can instead inject an instance of the Blogpost Model into the controller via it’s constructor. Let’s begin by adding this code to the controller:

Now that we have injected an instance of the Blogpost Model right into the BlogpostsController, we will need to remove all of the static references to that class and replace with the more traditional syntax. In fact, you could do a find on any Blogpost:: and replace with $this->blogpost-> , that will get our controller updated. Don’t forget to remove the $ symbol in front of your variables when making this change. When you reference a variable in a static fashion, it is included. An example is static::$messages vs $this->messages. Note that in the static example the $ is present, but in the dependency injection style only the $this keyword has the $.

If we test out the updated code, we’ll find all functionality to be the same. The benefit is that by using dependency injection and letting Laravel handle the creation of an object instance using the IoC container, we get code that is more dependable, testable, and flexible when a change in implementation is needed. The fully updated code looks like this:

BlogpostsController (controller)

Blogpost (model)

Of course this code could be made cleaner than this, but the goal here was to start by getting basic validation working. Once we got the basic validation working, we moved to more of a best practice style of dependency injection. Hopefully we accomplished those goals, and I think we did!