3.4 Storing and Updating Pages
With the views written, now we can actually store and update our pages in the database. Let's write that code!
1.Introduction1 lesson, 01:23
2.Getting Started4 lessons, 46:41
3.Managing Pages6 lessons, 1:12:31
4.User Management2 lessons, 27:37
5.Managing the Blog4 lessons, 41:51
6.Adding Extras2 lessons, 26:07
7.Implementing the Front-End3 lessons, 30:24
8.Homework Review1 lesson, 07:11
9.Conclusion1 lesson, 01:24
3.4 Storing and Updating Pages
In the previous lesson, we set up the views for creating and editing our pages. Now we need to actually perform that work. So whenever we click on the Create New link, we of course are taken to the Create New form. And whenever we submit that form the store method on our pages controller is going to execute. So that's where we want to get the data from the request, and store that within our database. So the first thing we want to do is get the user that is currently logged in because if we are going to associate this page with the user, we need to get that user. So, we need to add a use statement up here and we're going to use Auth. Now of course, the user needs to be logged in, that's very important and eventually we will get there. Whenever we start implementing the security, then that's going to be okay. But for right now, just make sure that you're logged in, otherwise you're going to have some issues and here's what we're going to do. We're going to say Auth and then we're going to use the user method to get the currently logged in user. And then we are essentially going to do what we did by seeding our database. We are going to get our pages and then we're going to call the Save method and we are going to pass in the data that we want. Now here's how we are going to do that, we're going to use our request, all of the data that is coming from the user is in this request object. And we could say, okay, we'll take all of the data coming from the user and we will save that. That is very dangerous because the user could be including extra information. Because there's nothing stopping anybody from coming to the inspector adding form fields and then submitting the form, nothing gonna stop them there. So what we want to do then, is we only want the data that we are expecting that is the title, the URL and the content. So we're going to say request only, we want only the title, the URL and the content and that is going to do just that. So let's break this up so that it's a little bit easier to read. We'll put our array there on another line. And that's going to be okay for right now, until we actually tried to do it. So let's refresh the page and let's just call this my first test and we'll have the URL of test and this is my content. So whenever we submit this, we get an error. Fatal throwable error, argument 1 passed to blah, blah, blah save must be an instance of blah, blah, blah, blah. Okay we can do that, we can do page, we will pass in that data and we will try that again. Let's go back let's refresh. My first test, /test, content goes here we submit, what do we get now? Another error, mass assignment exception. So what this means is that we are taking data from the user and we are trying to essentially mass assign the properties on our page object with the data that's coming from the user. Now, this is not an issue with Laravel, it's not an issue with PHP. This is an issue with any technology framework language that has implemented something like this. Where we can take just an object, which is essentially what we have with this request and we're saying okay, just mass assign these properties. And then they get mass assigned and then here, as long as you're careful, that's not that big of a deal. But if you're not careful, then things could get assigned that you don't want to be assigned. Like sensitive things like passwords and things like that. So what Laravel does is it protects us from this by default. There are some platforms that don't, you're just stuck, you have to be sure that you do exactly what you need to do. Laravel takes a good approach in my opinion, they protect us by default, we have to opt in to say that it's okay to mass assign these particular properties, title, URL and content. We might want to limit some of that if it was highly sensitive data like passwords, or things like that. But in this case, title URL and content is fine. So what we end up doing then is, saying that it's okay to mass assign title, URL and content. And so to do that, we go to our page model, and we're going to add a protected property called fillable. And this is an array and each item in the array is going to be the name of the property or attribute that is okay to mass assign. So that is title, URL, content, there we go. So if we go back, let's refresh the page. The reason why I'm going back and refreshing is so that the token is refreshed and so everything's going to match up. So once again, my first test URL is going to be /test content, this content goes here. So now whenever we submit this, it's going to save it, but we don't see anything on the page. Well, the reason being because the code did exactly what we told it to, it saved our page, but then it didn't do anything else. It didn't return a view, it didn't redirect anywhere, it just did nothing. So what we want to do after we save it is return back to our index, so we will return, we call redirect. Now before we redirected to home, whenever we did the middleware, if we look at access admin, we just redirected to home. Well, that is an actual URL, which we could do inside of our pages controller, but we have our named routes, and they are there for a reason. So instead, we're called redirect. But we're going to call a method on this and we're going to say route and then we will specify our route name, which is pages index. And so now If we go back, let's go to our form, let's refresh and we'll say Test Again. And then our URL will be Test again, content doesn't matter and we will click Submit. And we are once again, well not once again, we are now redirected back to our index. But notice that we now have our new pages, so great. Now let's write the code for editing. Editing is going to be very similar actually, we have the data already, or at least we have our object page. So what we're going to do is we're going to fill our existing object with the data that is coming from the request. I'm just gonna copy and paste because that is going to be easier. So we'll just copy that, we'll paste that and then we will save our page. So we'll say page save. But once again, we want to do the same thing. We want to redirect back to something we could redirect back to our edit form, but typically whenever we're done editing a page. It makes sense to go back to the index once again so that if we wanted to edit another page, then we could do that, same exact code. So let's just copy and paste that again and there we go. So let's test that out, let's test my first test. And we'll just add, edit and for the URL, let's change it to edited and then content goes here. I just wanna make sure if it's gonna edit anything, so let's add something a little bit different, we'll say edit content there. So we'll submit. We did not get an error but notice that the title did indeed change. If we go back in, the URL changed and the content changed. So we have creating, we have editing, and that's a really wonderful thing. However, the very first rule of accepting user input is to not trust user input, so we need to validate this data. And we can do that by creating our own form request, so let's do that. Let's go to the command line, let's stop artisan from serving this and we are going to say php artisan make request, and then we need to name this. Now typically we have a single request object for a single request. So we would have like store page, for the store method and then we would have update page. But we have the same exact information and really we're going to have the same exact validation rules for both of those, so let's call this something other than those two things. Let's say work with page, maybe. One of the hardest things in programming is naming things and that is exceptionally true with me. So this might not be the best word but It's going to work. So this created a new file, inside of app HTTP requests and here we have orc with page. And we have two methods we have authorize and then we have rules. Now the authorize method is very useful because we can write code inside of this method that would determine whether or not this request can be performed by the user. Right now, we're just going to make that true. And then as far as the rules are concerned, we can specify if any of the fields or the attributes are required, if they have a max length or things like that. So we have title and we are going to say that the title has to be required. In fact, we're going to say that for everything, so we will say title URL is required and we will also say the same thing with content. There's really no use in having a page if we don't have these three things. Now there are many different validators that we could use and if we wanted to, we could add other validators by using a pipe and then whatever validator we wanted to use. So if we wanted to have a max character link of 10, for whatever reason on the content, that's what our validator would look like it would have required and then the pipe and then max:10. But let's just stick with required. So now what we need to do is go back to our pages controller, and instead of type hinting the request here. We're going to type hint our work with page and we will do the same thing for our update method. And Laravel is going to automatically perform that validation for us, we don't have to worry about that whatsoever. So let's go to the command line, let's run php artisan serve so that we have that running. Let's go to the browser, let's refresh the page here, hopefully we are still logged in we are. Let's create a new page, and we'll say test with validator. We'll first have a test that's going to pass everything. So test with validator, hopefully this works. And we will see, of course not because I didn't add a use statement, duh. Okay, so use App, Http requests and then work with page. Okay, he knows the important things that you always forget. So we'll say test with validator, and what was this test with validator? Hopefully this works and after we submit we see our new page in the list. Now let's go back to our create form and let's submit this without entering any data. Because we know that these are required, we know that this was an invalid request and notice that it didn't take us back to index instead it just reloaded the page. So what we want to do is display some messages and thankfully, whenever you use a request object and you are validating your model, there are error messages that you can display. And it's automatically passed to our view as a variable called errors. So let's do this inside of views so that we don't have to go to the create or edit views. And we are going to check to see if we have any error messages. So let's say at if and errors or not errors is empty, then we have some error messages that we want to display. So we're going to start with a div element that has a class of alert and alert danger. That way the user can immediately see that something is wrong. So that is good and then we want to loop over all of our errors and display them. Now we do that like this, let's have a for each, or before we do that, let's have a ul element. And then inside of the UL element, we will have our for each, and we're going to say errors all. We're going to get all of our errors, as and let's just call that message. And then we will display the message in an Li element. So in for each and then Li, we will output the message. So whenever we go back to the browser, let's resubmit and we see our error messages that title field is required and so on and so forth. These are the default error message, but we can override them if we want to. We need to do that inside of our work with page class. So we are going to override a method called messages, this is going to return an array, where the keys are the name of the field and the validators. So, we would say title.required and then we will specify whatever we want this to be, you must enter a title. Now this isn't going to change any of the other messages just for the required title. So if we go back and refresh, will not really refresh, if we resubmit, we can see that the message for our title field changed to what we specified. But the other fields are using the default message, so we can come back and in this case, let's just please enter some content. So there you go. So if we go back, we submit and we see our custom error messages. So we now have a working pages controller. We are reading the data, displaying the index we're creating, and we are editing. In the next lesson we're going to talk about security because in the case of working with our pages, it's not good enough to just protect our controller. We also want some granularity based upon our roles and we will look at that in the next lesson.