Identify Missing Validation 0:00At this point, we definitely need to add validation. So currently, if we were to add a note, yeah, the system would allow us. So we would insert a new row where the body of the note is blank. We definitely can't allow that. But second, do you remember how at the end of the last video, we added support to display the username of the person who created it? Well, think about it. We didn't factor that into our creation form. So now if we add a note, it's going to fail, right? And that's because it expects a user ID, but we're not passing one in.So now if we add a note, it's going to fail, right? And that's because it expects a user ID, but we're not passing one in. So we get an integrity constraint violation. Okay, let's fix both of these in this lesson. Now, actually, on that note, real quick, a few of you noted that you didn't see the relationship between a note and a user. So just in case I didn't include that portion, yeah, it's pretty self-explanatory. A note belongs to a user, or you might even call that an owner if it's more readable to you. But yeah, either way, the relationship will be a belongs to. Associate Notes to Users 0:56you. But yeah, either way, the relationship will be a belongs to. Okay, let's get back to work. So I'm going to switch over to my notes controller. Here's the section where we submit the form and we trigger this bit of code, where we new up a note, and then we pass that to this add note method, where we reference the relationship. So yeah, notice that at no point did we designate a user ID. Let's take care of that now. And in fact, I'm going to show you two different ways to do this. So here's what a lot of people do to start.And in fact, I'm going to show you two different ways to do this. So here's what a lot of people do to start. So right now, we have the form to display a specific card. So for example, on this page, yeah, that's loading this view here. So yes, we filter through all of the notes for the card and display each one in a list item. And actually, on that note, one of you were nice enough to tell me what that class name was. It's pull right. Okay, but anyways, if we scroll down, here's the note to create a form. Avoid Hidden User IDs 1:46It's pull right. Okay, but anyways, if we scroll down, here's the note to create a form. So yeah, once again, no reference to the user who created it. So here's what a lot of people will initially do. And it'll work, but you might want to be careful. So they will think to put a hidden input. They'll set the name to user ID, and then they will set the value equal to the ID of the authenticated user. So the person signed in. Now it's true, we haven't yet reviewed how to sign in your users.So the person signed in. Now it's true, we haven't yet reviewed how to sign in your users. But don't worry, it's actually really easy. So for the time being, I'm just going to fake it and put one. So that should correspond to this user. If we find all users, yeah, that user with an ID of one, I'm hard coding it for the time being. So that means if we were to well, first, if we go to the note model, let's make sure that we add user ID to the fillable fields, we may or may not want to do that. But yeah, if we allow that, that means when we fetch all of our request data, it willthat we add user ID to the fillable fields, we may or may not want to do that. But yeah, if we allow that, that means when we fetch all of our request data, it will include the user ID as part of that. Which means this will suffice. If I come back to Chrome, give it a refresh, click add note. Yeah, we're no longer getting that error. We still have the validation bug, of course, but we'll get to that in just a minute. But yeah, we are passing through the user. But here's the problem. What's to keep somebody from going in here and changing that value to how about two?But here's the problem. What's to keep somebody from going in here and changing that value to how about two? Okay, so new note, add it. And now in this case, it's entirely failing, because well, the user was able to, if we put this up again, they were able to add a note and assign it to a user who does not exist. So this is one of those scenarios where you have to be pretty careful. If you're just going to assume that the person filling out the form is honest, well, it's very possible they will not be honest. And this becomes quite a bit more extreme when it comes to what if we were deletingvery possible they will not be honest. And this becomes quite a bit more extreme when it comes to what if we were deleting the user and we were depending upon an ID from the form? Well, a random user then has the ability to delete any user. Not a good idea. Okay, so we're going to change this up instead. I'm going to go back to our show view, and I'm no longer going to put a hidden input. Okay, so anyways, I'm going to come back and remove this user ID is no longer a fillable field. So that means at this point, at some point, we do need to pass through the user ID.field. So that means at this point, at some point, we do need to pass through the user ID. And you could do this in a couple of ways. We could say, create a new note, pass through the request data. And then we could just manually assign it like this. And once again, if the user is signed in, you would ultimately be able to do that. Get me the authenticated users ID. But we're not worrying about that yet. So I will hard code it. Yeah, that would do the trick.So I will hard code it. Yeah, that would do the trick. So you could then say, add note like so. And this would work. So if I were to come back to Chrome, and by the way, we have to delete that faulty note. So app note, find by six, and delete it. And by the way, on that note, let's also delete the five as well, where we provided nobody. Refresh. Okay, so now think about the difference here. There is no longer a place for the user to modify the ID of the user to associate withOkay, so now think about the difference here. There is no longer a place for the user to modify the ID of the user to associate with this new note. They can't do it. So they can enter gibberish, but it's always going to be associated with whoever is currently signed in. And we ensure that by placing the logic right here, rather than fetching a parameter from a form. Now, what else? If you don't like this, you could always use maybe a fancy getter.Now, what else? If you don't like this, you could always use maybe a fancy getter. Not very fancy, but maybe you want a by method, you want to keep it readable. And you want to say note by my user object, or you want to say off user. Once you learn about this. Yeah, if you want to do that, then on your note class, you could add a method right here called by, except the user. And then you could assign it here. This note, set the user ID equal to the ID of the user passed in. Now, yeah, you could do that.This note, set the user ID equal to the ID of the user passed in. Now, yeah, you could do that. So create a new note, specify who it's by, and then add it. Or here's what you might do instead. Maybe you can pass the user as the second argument. Now again, we don't have a user. But in reality, you would. For now, once again, I will hard code it. So yeah, that would be an option. Now, if we go to our card, we would accept the note as well as the user.So yeah, that would be an option. Now, if we go to our card, we would accept the note as well as the user. So once again, in real life, we'd hard code user, or in this case, it's just going to be an ID. And that's fine, too. Okay, so now we set the ID of the user to the note. And then we save it. And now we contain all of that logic within the single method. Okay, so let's come back to Chrome. Give it another shot. Add Controller Validation 6:35Okay, so let's come back to Chrome. Give it another shot. And we should still get the exact same thing. But now, yeah, you might decide that it keeps your controller a bit cleaner. Now, that solves that issue for the time being. But what about validation? Okay, let's move on to that. Now, I want you to see something real quick. If we go to the parent controller class that this one extends, and all of your controllers will extend, you'll see that it uses a trait called validates requests.If we go to the parent controller class that this one extends, and all of your controllers will extend, you'll see that it uses a trait called validates requests. So if I take a look at that validates requests, yeah, let's see what's going on here. Kind of complicated stuff. But most importantly, yeah, we see a validate method here that accepts a request as well as an array of rules. Okay, so does that mean in our controller, at any point, we can call a validate method and then pass through, well, the request, and then also an array of rules? Interesting. Okay, well, let's try that out.Interesting. Okay, well, let's try that out. Now, what rules, like how does this work? Well, we're going to have rules that correspond to the items within the request array. Or in other words, right here, we're passing through a body, and that's it. So what if I just want to say a body is required? Well, of course, on the HTML5 side, yeah, add the required parameter, and that gives you some browser protection. But I'm leaving that off just to show you what happens if it fails. Anyways, if we come back, yeah, let's just say the body parameter is required.But I'm leaving that off just to show you what happens if it fails. Anyways, if we come back, yeah, let's just say the body parameter is required. Nice and clean. Very, very simple. So let's try it out. I'm going to come back, give it a refresh, add notes. And interesting, right? It definitely didn't work because we don't see it here. But at the same time, we didn't get much feedback. All right, well, let's try it to see if it's really working.But at the same time, we didn't get much feedback. All right, well, let's try it to see if it's really working. I'm going to delete this temporarily, add the notes. And yeah, it did add that empty row. But if we bring this back, refresh, and try it again, it's not allowing us. So what exactly is happening here? All right, well, here's the deal. When you call this validate method, Laravel's automatically going to perform the validation using these rules against the request object that you pass in. Now, if at any point the validation fails, a exception will be thrown, and Laravel thenusing these rules against the request object that you pass in. Now, if at any point the validation fails, a exception will be thrown, and Laravel then takes care of catching that exception for you. And this is a little advanced. But if you want to take a quick look, let me look for a redirect. Yeah. OK, if we failed validation, we're going to redirect to the redirect URL. And that will, by default, be the previous page. So we're redirecting back. We're populating the form input.So we're redirecting back. We're populating the form input. And we're also passing through an errors variable. OK, so now what we can see is it failed validation. So it redirected back to this page. And it also sent through an errors variable. Interesting. So let's review that. We're going to go right here. And at the bottom, I'm simply going to var dump the errors.We're going to go right here. And at the bottom, I'm simply going to var dump the errors. And notice, I didn't have to manually pass through errors. And in fact, every single view can access this variable. So you never, ever have to check whether it exists. But if you're working along, you may try that. And you may see that everything I just said was a lie. So what's going on with that? Well, here's where we get into, at least briefly, this is where we get into group middlewares. Enable Web Middleware 9:59Well, here's where we get into, at least briefly, this is where we get into group middlewares. Now, I've kind of been putting off middleware. For now, think of middleware as like layers of an onion. So when a request is made to your application, it will filter through any middleware that you register. So let's take a look. Right here, we have a group called web. And notice all of these various middleware, like encrypt cookies, add queued cookies to the response,And notice all of these various middleware, like encrypt cookies, add queued cookies to the response, start up the session, share errors from session. Notice that. That's the errors variable I was talking about. And then finally, verify CSRF token. Okay, now you can create your own middleware once you get to that point. But for now, well, we have them defined within this web middleware group.But for now, well, we have them defined within this web middleware group. But in our routes file, I'm not referencing that anywhere. And if you remember, if you've been working along in the very first video, just to keep it simple, I removed that section from the routes file. So now we're going to bring it back. However, just to prove it to you, when you install Laravel for the first time, here's what you're going to get.when you install Laravel for the first time, here's what you're going to get. App, HTTP, routes. And this is what it looks like. So notice right here, your application routes. Let's go ahead and return that now. We're going to come back, build this up. And now for any routes that will be accessed from the web, I'm going to nest it like so. And then we will indent these.I'm going to nest it like so. And then we will indent these. Now, so here's what happened. Because we've applied this web middleware group, that means for any single request to one of these routes, yeah, we're going to send it through all of these checks right here. Okay, so now take a look. Before, it didn't have an errors variable. But now we're using the web middleware group.Before, it didn't have an errors variable. But now we're using the web middleware group. So if we refresh, we do have an errors variable. And trust me, if that was confusing, it's okay. Those are some higher level concepts, at least for where you are right now. Until you feel a bit more comfortable, just remember, this section comes right out of the box. So as soon as you are ready to add web-specific routes, you will place them right in hereSo as soon as you are ready to add web-specific routes, you will place them right in here anytime you install Laravel. Okay, so anyways, back to validation. Let's add a note. Now, in this case, notice we don't have any errors. So the size is zero. If we add a note though, well, now we get a different error. Do you remember when we were talking earlier about CSRF and how Laravel protects you?Do you remember when we were talking earlier about CSRF and how Laravel protects you? Well, it's only going to protect you when you have that web group middleware applied. So what's happening here? Well, it's trying to check the token from the form against what it has stored, but we couldn't find one. So they didn't match up. So it's assuming, hmm, something might be funny here. Okay, well, that's why for all of your forms,So it's assuming, hmm, something might be funny here. Okay, well, that's why for all of your forms, you want to include a token. And luckily, we make that really easy. If we come back for any form, yeah, you can just say CSRF token. Well, to start, let me show you this one. Here's one function. And if we were to come back, give that a refresh, you'll get this unique hash right here. However, we want that to be part of the formyou'll get this unique hash right here. However, we want that to be part of the form and sent through the request. So we could also do CSRF field. Okay, now if I give that a refresh and view our source, you'll see that will basically return to you a hidden input that has the token there. So yeah, basic rule of thumb. Whenever you create a form, make sure it includes a CSRF field, and this will give you a bit more protection.Whenever you create a form, make sure it includes a CSRF field, and this will give you a bit more protection. Okay, cool. So we're getting sidetracked, but we're still focused on our validation. So I'm going to add a note. It will fail the validation. So as we learn, it redirects back and populates that error message back. And now we can see the size is one and specifically a note that says the body field is required.And now we can see the size is one and specifically a note that says the body field is required. And think about how nice this is. You got all of that simply. And by the way, I'm going to close all these other tabs. Anyways, we got all of that simply by calling a single method. Very simple. There's nothing special you have to learn. Okay, so now at this point, we don't want to echo that out. Show Errors and Old Input 14:07Okay, so now at this point, we don't want to echo that out. We just want to filter through the errors and inform the user. Like this. Go back to our view. And now I will say, if count errors, if we have any errors, then let's filter through them and display them on the page. Like this.then let's filter through them and display them on the page. Like this. For each errors, all as error. Then within a list item, let's echo out the error. And that's it. So let's come back, give it a refresh, trigger failed validation, and now we're all set to go. Now what's cool about validation, we'll talk more in the future about it,Now what's cool about validation, we'll talk more in the future about it, but what's cool is it's basically exactly what you would expect. So if you have additional validation requirements, you can separate them with a pipe or you could always use an array like this. Required and then unique. That would make sense in this case. But yeah, you get the idea. You can pass an array or you can separate them with a pipe like this.But yeah, you get the idea. You can pass an array or you can separate them with a pipe like this. Required, maybe you have a minimum number of characters you expect. There's lots of options here. So with that in mind, if you visit laravel.com slash docs slash validation, you'll see a big list of all the rules you can reference. So for example, maybe the form has an email section. Okay, well then you could use rules like this. So we could say,Okay, well then you could use rules like this. So we could say, okay, for the email field, whatever the user filled out, we want to make sure that it is in fact an email. So it should be formatted like an email. But also you could imagine that when a user signs up, we want to ensure that they provide a unique address. So we don't want the guy with john at dough.com signing up over and over and over with the same address. Instead, that needs to be unique in the database.signing up over and over and over with the same address. Instead, that needs to be unique in the database. So you could do something like this. Unique. But now specifically, we have to tell the validator, well, unique on what table? So you could do something like this. And by the way, this is not related to adding a node. This would be like a creating a user example. But yeah, now we could say for the email field,This would be like a creating a user example. But yeah, now we could say for the email field, it needs to validate as an email. And it also needs to be unique on the users table. And you could even be specific if you need to. So the user column in the users table. Yeah, this field needs to be unique there. Okay, but in our case, all we really care about is that they do pass a body. Now, if you want, we could say men,all we really care about is that they do pass a body. Now, if you want, we could say men, let's do this as an example. So we want a minimum of 10 characters here. So if we tried that one out, let's give this a refresh. Well, we add the nodes and we can see the first failure. So let's add a single letter, add the nodes. Well, now we're onto a different error. This time, well, you filled something out, but we expected at least 10 characters.This time, well, you filled something out, but we expected at least 10 characters. So now you can imagine this could be a problem because you fill something out, you add the nodes, but then you have to start all over again. So it would be nice if we could automatically populate that input for the user. And we can definitely do that. Down here, I only need to say old body. Okay, let me prove that this worksDown here, I only need to say old body. Okay, let me prove that this works and then we'll talk some more. So add some gibberish, add the nodes, and now it's populated there. Okay, so do you remember how when we reviewed that validates request section, and we learned that when validation fails, we redirect back with the input? That's referring to the old inputwe redirect back with the input? That's referring to the old input from the previous request. So to reference this, all we have to do is say, yeah, give me the old value for this body parameter. And alternatively, if you had like a username or something, so name is username. Well, then you would say value equals old username. Like that. Once again, very simple,Like that. Once again, very simple, pretty much exactly what you would naturally do. All right, so yeah, that'll basically take care of a number of things in this lesson. So you learned about validation, you learned about referencing old input, and you also learned about some ways to associate a record with multiple foreign keys.to associate a record with multiple foreign keys.