Need Input Validation 0:00In the previous lesson, we finished up by making note of the fact that even if we don't insert a value as the username and password, if I click create user, it will in fact insert an empty value into the database as we can see right here. Clearly, that's not what we want to do. Instead, let's write some validation to prevent this from ever happening. Back within our project, if I visit my users controller and I scroll down to the store method, this is where we handle the creation of a user. So what I want to do here is first validate the provided input, and if it does not meet my criteria, then I want to not create a new database record, but return to the previous page and let the user know that they forgot to do something.my criteria, then I want to not create a new database record, but return to the previous page and let the user know that they forgot to do something. Now we will tackle this in a couple steps, and this is one of the great things about Laravel. It grows with you. So while there are basic, simple ways to go about it, as your need for flexibility and testability grows, you'll find better, more optimized ways to go about this. But that said, let's take baby steps. We'll start with the absolute basics. In our case, we can leverage Laravel's validator class. Using Validator Class 1:03We'll start with the absolute basics. In our case, we can leverage Laravel's validator class. So I can say validator equals validator make, and I need to provide the input, that will be the post data, as well as a rule set. For now, I will hard code it in. Username is required, as well as the password, that should be required as well. Notice that we have an array where each key refers to a field in our database table, and then the value for each key represents some kind of validation. And you can check the Laravel documentation for a huge number of configuration options for your validation.And you can check the Laravel documentation for a huge number of configuration options for your validation. All you need to do is separate each rule by a pipe. In our case, just making sure that they are required is enough for us. Next we're going to say, if the validation here does not pass, then we want to go back. So let's do this. If the validator fails, in that case, why don't we just return failed validation, just to see if it works. Now if I click create user, sure enough, that did work. So at this point, all we need to do here is say something like this. Redirect Back With Errors 2:04Now if I click create user, sure enough, that did work. So at this point, all we need to do here is say something like this. First, why don't we change this to validation, just to make it a little more readable. So if the validation fails, in that case, why don't we return back. So return, redirect back, and I want to make sure that I fill the input with what they entered so they don't have to fill out that form again. Next I also want to send through the errors. Now how do I grab these error messages? Well, we can send through the validation messages, like so. Now if I were to open a new tab and return to that user's create view, within each div,Well, we can send through the validation messages, like so. Now if I were to open a new tab and return to that user's create view, within each div, why don't we add this, errors first, username, like so, and let's simply copy that and paste it below. If I click create user, there we go. Here's our validation messages, and you can style those however you wish. Now if you do want to wrap them, you can do something like this. You could say wrap them within a span that has a class of error, and then we can paste in the message there. Think of that as a placeholder.in the message there. Think of that as a placeholder. Now if I were to come back and refresh, create user, you'll see that now that is wrapped within a span. But I will go ahead and undo that for now. Alright so now what if I enter a password but not a username? Well, that validation message disappears, however notice that it doesn't repopulate the password, and obviously that's for security, so that's exactly intended behavior. However now, let's see if it'll work with a real username. Provide a password, create user, and there we go, that did work. Extract Rules to Model 3:34However now, let's see if it'll work with a real username. Provide a password, create user, and there we go, that did work. So now we have a modest validation system in place, however this isn't 100% ideal. For example, we have stored the rules for how a user should be validated directly within the store method. So when deciding whether this is appropriate, ask yourself, could there be any other instance when I would need to validate a user? If the answer is yes, and of course it is, then we need to extract these rules out of the method. Now, once again, there are many levels to this.the method. Now, once again, there are many levels to this. For example, we could extract this to our model, and that's what we will do in this lesson as a first step. However we could also create an entire validation layer and create validation services. Or we could even hook into model events and perform automatic validation. There's lots of different ways to go about this. Like I said though, let's begin by simply pasting these rules into our model. If I open up the sidebar, we're going to go back into models, and I will open up our user model within a new tab.If I open up the sidebar, we're going to go back into models, and I will open up our user model within a new tab. Now at the very top here, let's create a public static rules, and this is where we will store those. So now once again, username is required, and password is required too. Alright so now we have a dedicated property for storing our rule logic. Next if I go back to our users controller, we can simply replace this with user rules. Let's now return to the browser and see if it still works. Create user, and we still get the same thing. Next though, why don't we take it just one step further. Add Model isValid Method 5:10Create user, and we still get the same thing. Next though, why don't we take it just one step further. And this won't be ideal, but we can always improve it later. What if we said if user is valid, then we can continue on. Or if the user is not valid, then we want to do what we did before. So in that case we could just remove all of this and paste it in like so. Now ask yourself, is this a bit more readable? When attempting to create a user, if they are not valid, then let's go back. However now we have this issue of the validation messages. How might we fix that?However now we have this issue of the validation messages. How might we fix that? Well let's return to our user model and take a look. First at the bottom, we need to create that method, is valid. Now I can paste in that old logic here. Next while we could try to reference the input in that way, generally I think that's a bad practice. Instead, I want this to accept the input, or why don't we call it data. Now we can remove this entirely. Next because we are in the user class, I don't have to refer to it that way.Now we can remove this entirely. Next because we are in the user class, I don't have to refer to it that way. I can simply say static rules. Now we can perform that same check. If validation passes, then let's return true. Otherwise we are going to return false because it failed, however I also need some way to fetch those validation messages. So why don't we do this. Static messages equals validation messages. This would be one way to go about it.Static messages equals validation messages. This would be one way to go about it. And honestly it's not the most ideal, but it's a good first step to extracting some of this logic out of your controller. So now when this method is called, we instantiate our validator. We provide it our data. We also compare that against the rules for a user. And if everything passes, let's return true. And in fact we can even clean this up like so. Otherwise we will assign the error messages to a messages property and return false.And in fact we can even clean this up like so. Otherwise we will assign the error messages to a messages property and return false. Now I will simply create that at the very top. Public static messages. Now notice how we're using a lot of statics here. Honestly that's not ideal, but we will improve that shortly. For now let's just get it to work. So if I now return to my users controller, we can replace all of this with user messages like so. However if that's not quite as readable to you and you'd rather call that errors, oflike so. However if that's not quite as readable to you and you'd rather call that errors, of course that's perfectly fine. Let's update that. And then at the bottom I of course need to make this static, at least for now, and then update the static property here. Okay, so we are just about ready to try this out. The only remaining thing I want to do is pass in the input. All right, let's try it out. So now if we try to create user, we get the exact same thing as before, but now we've Plan Dependency Injection 7:45All right, let's try it out. So now if we try to create user, we get the exact same thing as before, but now we've extracted some of this logic. That being said, I think there's still room for improvement. Really, rather than referencing the user directly as we've done here, instead I'd rather inject this dependency through our controller's instructor so that we can avoid using these static methods. We will do that in the next lesson.