5.2 Storing and Updating Posts
We've done all this before—CRUD is (re)used in just about every app. In this lesson, we'll write the code to store and update posts.
1.Introduction1 lesson, 01:23
2.Getting Started4 lessons, 45:12
3.Managing Pages6 lessons, 1:12:31
4.User Management2 lessons, 27:40
5.Managing the Blog3 lessons, 42:25
6.Adding Extras2 lessons, 25:48
7.Implementing the Front-End3 lessons, 32:10
8.Homework Review1 lesson, 07:11
9.Conclusion1 lesson, 01:24
5.2 Storing and Updating Posts
In the previous lesson, we had started implementing our blog management. And we created all of our resources such as the model, the migrations, the seeder, the controller. And we also implemented the index view or at least part of it. There's still some things that we need to do here. So in this lesson, we need to do the rest of the crud stuff, create, update, and we will be deleting. So if you haven't looked at the page's delete homework, then feel free to do so, because I'm going to use that here. I'm not going to explain it in this case, because it's been explained in that. So you're not going to be missing really anything if you haven't viewed it, so don't worry about that, but if you're curious, go ahead and do that. So let's go ahead and start with our BlogController, and we'll start with a create method. And all we need to do is return the view, admin.blog.create and just like what we did with our pages, we're going to parse in an empty model object. So new post and there we go. That's it for that method. Let's go ahead and write the store method as well, because it's going to be practically the same for our store method on our pages. So the first thing that we're going to do is save this as one of the user's posts so that it will be associated with that user. So then we will create our Post object, and we are going to get data from the request which we need to create a request object, but we can do that here in a few moments, so $request→only. And we have the title, we have the slug, we also have published_at, and excerpt, and finally, body. And let's break this up a little bit so that it is all on the screen without having to horizontally scroll. So there we go. But that's not enough. After we save this, we need to redirect back to the index. So we will return redirect, we'll specify the route as blog.index. Let's also provide a status method since we have that capability now. So status, or not status, with status, [LAUGH] and then the post was created. All right, so that is good for now. Let's go ahead and look at our views. So let's open up both the create view as well as the partial view for our fields. So admin, blog, create, and partials. The create view is going to be very simple. We simply change our page's reference to blog, and we are done. So there we go, let's go ahead and close that file. But inside of our fields, we have quite a few changes. We have the title, so we're going to keep that. Now we don't have the URL, instead we have a slug which is part of a URL. So let's change all of our URL references to slug, and that will be good there. Let's take this and copy and paste it for our published. And eventually, we will add some components, well, not components, we're going to add a date picker, so that it will be a little bit easier for the user to specify the date and time. Otherwise they will need to type it in the correct format, and it's just easier if we do that for them. So as far as our references are concerned, that is all published_at, and we will be doing that probably in the next lesson. In this lesson we're just going to get all of the CRUD stuff, in the next lesson we will add some polish. So we have our title slug published at, our content is not content anymore, it is simply the body. So let's go ahead and change those references as well. We will change the text of the label to body. And we will copy this, because we also have the excerpt as well. So once again, change our body references for this field to excerpt and then we will change the label text to excerpt. Okay, so let's at least see the create view, and that looks pretty good actually. And also one thing we will do is automatically populate the slug, we will let them choose ultimately. But as I type the title, we will autopopulate the slug and that will be done in the next lesson as well. Okay, so let's go ahead and create our request classes. And yes, I mean classes. So unlike the pages, I'm going to create two request object, or two request classes, one for storing and one for updating. And we will use one as the base class for the other, because they are going to have the same exact functionality. That's just the better approach, really. So we've created those two classes, store blog request and update blog request. Let's go to our request folder. And let's implement our store blog request. Now the authorize is going to return true. And as far as our rules are concerned, practically everything is going to be required except for the published dates. So let's go ahead and copy or paste a few times. The slug is required, the published_at is going to be the only thing that's going to be different. This is nullable. And if there is data, we want it to match the date_format of year, month, day, hour, minutes, seconds, so Y-m-d H:i:s. And then we have the excerpt and finally the body. Now we could implement our own custom error messages if we wanted to, but this is going to be fine. So let's open up our updates blog request, and let's extend our store blog request and we will get rid of everything else, because we don't want to override anything. And there we have those. So we can use them inside of our blog controller, but let's import them first. So we'll say App\Http\Requests\StoreBLogRequest and then one for our update. Let's go ahead and use them in our methods as well. So for the store method, we are going to store blog request, and that's wrong, excerpt, I'm glad I caught that. [LAUGH] It's always great to catch it when you don't run it or before you run it. And then update blog request. Okay, so let's test this out, and then we will come back and implement the edit. So let's Create New. So for the title, this is a test. The Slug, this-is-a-test. The Published Date, we'll leave null. This is Excerpt, and this is Body. So whenever we submit, we should see our test. That's great. And everything works okay. So let's go and edit this. Now of course, we need to first of all, return our view. So for the edits we will return view, and that is admin.blog.edit. Now we do need to parse in the model. So with model, but in this case we can't use post here. In fact if we do, it's not going to work, because the model binder isn't going to bind our data correctly. This needs to be called blog. So we are going to parse blog to our edit view and we will see that there. So let's go to Our Views. And let's open up Edit. We shouldn't have to do anything inside of our fields, but we do need to change our edits so that instead of referencing pages, we reference blog. And let's also change this to blog model id, okay. And you know what? I guess we should also go to index and wherever we have this link, instead of saying post, we'll say blog. All right, so let's refresh the page here. What do we have? Undefined use of constant blog, assumed blog. And yeah, need a dollar sign. So let's go back to the controller. Let's add a dollar sign, there we go. Now whenever we refresh we should see our form, and we do all of our data is populated, so that looks good. Now we just need to implement the update method. So really what we want to do is do the same thing with the pages. We want to have a policy that we can use so that only users who are admins, authors with the ID of the author ID of the post, and editors. So let's go ahead and make that policy. So we'll go back to the command line php artisan make:policy, this will be called PostPolicy and the model is going to be a post. So we have that, we do need to register that in our Auth service provider. So let's go there and we will say App\Post has the policy of App\Policies\PostPolicy. Okay, so that's wired up. Now we do need to actually implement that, so let's go to our policies. Let's open up our page policy, because really, a lot of that's going to be the same, although I never changed that back to update. Wow, I apologize. Let's go and quickly do that. So let's find foobie, let's change that to update and find the next one. And I think those are the only two places where we used that particular policy. So, that's going to be fine, okay. So I apologize for that, that should have been changed long time ago. Okay, so we want this before, so let's go ahead and add that to our policy. So inside of PostPolicy, we have the the before method, if the user is an admin or editor, then we return true. We're not using the view, so we will get rid of that. And every user can create something, so we will get rid of that. But as far as updating is concerned, that's where we're going to pretty much do this. If the user_id is the same as the post user_id, then that user can do it and I don't know about delete. This isn't like pages, these are blog posts. But what do we do with the page, we did the same thing. So I guess we can do the same thing here as well. So we will do that except page is going to be post, and there we go. So let's use this policy, if off user can't update, and then we will parse in that post which we need to call blog. The can't update, that post. Then we want to redirect back to index. So our route is blog.index. We also need a status, and this is a permission thing, we can say you do not have permission to edit that post. But if they do have permission, then we of course want to edit. And after we edit, we want to redirect. But in this case, we'll say that the post was updated. So we have that, now we just need to update and we will use our blog, we'll call the fill method, and we will fill it with the data from the request. So we want only title slug, published_at, excerpt, and then finally the body. And that's not enough, we need to save it as well. So we will save. And then after we save, we will redirect. So with that implemented, let's test out the editing. So let's change this to edited and the slug we could also say edited, we'll leave the published date null as well, we'll leave everything else alone, let's submit. And what do we have, the post was updated, and we can see that it was updated. And so finally the last thing that we need to implement is destroy. So we will essentially do what we did for update, in that we are going to check for our delete ability. And if that is not available, you do not have permission to delete that post. Otherwise, we will delete it, so blog delete. And then we will redirect back to our index, and we will say, The post was deleted. And then to make that work, let's just grab what we have from our pages. So let's go to our views, pages, index. And we want this link for deleting, that's add that to this empty cell there. We also need the form that's actually going to be used to submit that request. So we will copy and paste that in, and there we go. Although that cell that we've put that in was for the publish. So let's add another header field, one that doesn't have anything and then we will add in another cell there, in between our delete and the slug. Now as far as what we have here, this needs to be blog.destroy, the page needs to be blog, that needs to be post and everything else is okay. So let's test deleting. And if we click on delete of this, yes, we want to delete undefined variable blog. So let's get to our controller. When you try top do things to fast, this is what happens. It always gets me, I tell you. All right, so let's try that again. We will try to delete, and voila, that worked. Well, now that we have finished all of the crud for our blog management, we want to add a little bit of polish to our views. We want to auto populate the slug as I type the title. We also want to provide a date-time picker to make entering the published_at value easier.