Using Forms for Delete2:02
So if I make a request to view the homepage, it's always going to show me the homepage. Compare that to a request to delete a note, or to add a product, or to update a product. Those things are not idempotent, and as such, we should probably not use a standard GET request, which is what an anchor tag will do for us. Okay, so instead, we will store this within a form, and then I will add a submit button that says delete, and yeah, if you want, we will make it small and red. Okay, also we should have just a little margin above this form. Come back, give it a refresh, and yeah, that's good enough for now. Okay, so now when I click on this, well, of course, by default, it's going to submit a GET request to the current page.
Okay, so now when I click on this, well, of course, by default, it's going to submit a GET request to the current page. So we could change this to a POST request, and if I come back, we try it again, and yeah, the page just effectively reloads, even though we did submit a POST request. And that's because, well, think about it. Let's have a look at our routes section, and yeah, right here is our current URI. So we now submit a POST request that loads the show controller, and this just displays the note. So there's no change. In other words, when we submit a GET request versus a POST request to this specific controller.
So there's no change. In other words, when we submit a GET request versus a POST request to this specific controller. But yeah, if you want, we could do it right here. I could die and dump the current server, superglobal, and if I come back and I now submit it, sure enough, we can see that we are submitting a POST request to this page. Okay, so yeah, I guess once again, we could do this weird check where we say, all right, if the request method, and again, I'm just grabbing that right here, that's the name of the item, if that equals POST, then, well, we're just going to assume that's a request to delete the note. But again, maybe it could be a request to update the note.
RESTful Delete Convention3:54
to delete the note. But again, maybe it could be a request to update the note. So this is where you really have to think about the structure of your URIs. So another option, if I were to come back to my routes section, you might think, well, let's use a completely different URI. So for example, we might say, excuse me, note slash delete should take us to a different controller. And yeah, I guess you could do it if you want. And in fact, it's actually a really common approach, but I don't really love it. And worse, if I teach you this approach, in a handful of episodes, I'm just going to unteach
And in fact, it's actually a really common approach, but I don't really love it. And worse, if I teach you this approach, in a handful of episodes, I'm just going to unteach you. So instead, I really do want to stick with a common RESTful convention here. And that convention says, if you want to delete a particular note, then you should submit a DELETE request to that specific note endpoint. But now we have more problems, lots of problems here. As it turns out, current browsers and forms do not support request types that are not GET or POST. So if I want to submit a DELETE request or a PUT or a PATCH request, usually for updating
GET or POST. So if I want to submit a DELETE request or a PUT or a PATCH request, usually for updating a resource, well, forms don't really understand that. So now, if that's the case, and we still want to use these request types, our application has to be updated to support it. And we need to provide some kind of hint to our application to say, OK, well, the form doesn't support submitting a DELETE request, but that's really what I want. All right, so we got to figure out how to communicate that as part of our application. So here's what we'll do for now. If we come back into notes/show, I'm just going to stick with a simple POST request.
Handling POST in Controller5:32
So here's what we'll do for now. If we come back into notes/show, I'm just going to stick with a simple POST request. And then in the coming episodes, I'm going to show you how we can rewrite things to make it a little more, I don't know, a little more seamless. OK, so let's come back into notes/show. And yeah, it sounds like this is what we have to do at the moment. We check. Well, if you submitted the page, then we want to take this pathway. Otherwise, we're going to take the pathway that you see right here, give it a reformat. Notice how already it just feels gross.
Otherwise, we're going to take the pathway that you see right here, give it a reformat. Notice how already it just feels gross. The more if-else statements you add, the more complexity that you add as well. And then if within one if statement, you add another if statement, very quickly, things can go off the rails. And you will encounter this over and over in your own projects. OK. But yeah, we'll just say form was submitted. Delete the current note. OK, so how could we do that?
Deleting Note by ID6:30
Delete the current note. OK, so how could we do that? Well, we just need to write a query. So I could say DB::table('notes')->delete(), and let's write a delete SQL query. DELETE FROM notes WHERE id = ? that should be passed through the form or when we submit the form. But at the moment, you can see we're not actually submitting anything as part of the POST request. OK, so why don't we do this? Let's add an input that's actually hidden because I don't want the user to see it. Or in other words, if I keep it like this, and then we set the value equal to the $id
Let's add an input that's actually hidden because I don't want the user to see it. Or in other words, if I keep it like this, and then we set the value equal to the id of the current note. So I could do something like this, noteId. OK, so if we come back to Firefox and give this a reload. Yeah, sure enough, we now have the id of the note, which is 17. And that will be submitted when we press this button here. But there's no reason to show this input to the end user. So instead, I'm going to create an input with a type of hidden. That way it exists and it will be included along with the POST request.
So instead, I'm going to create an input with a type of hidden. That way it exists and it will be included along with the POST request. But the user doesn't have to see it. OK, let's prove it. Let's go back into our controller here and say, well, before we do anything, let's dd($_POST), and then we'll give this a shot. So refresh, and I will delete it. And that didn't work. What did I do? See, I talked a big game, and then things don't even work.
Authorization for Deletion8:17
But sure enough, we are sending it through. OK, great. So now, yeah, all right, come back here, uncomment this, and we could say delete from notes where id = $id of the note that was included along with the POST request. But now remember, we need proper authorization. Otherwise, anyone could make this request. Even if I don't have an account, if I knew that you had this security concern, I could manually make this request and start deleting the notes of all of the users in your system. And I could even create a loop where I just go through every single id, and I try to delete the note.
Redirect After Deletion9:41
But in the next section, I think we will take a look at that and everything's just going to work seamlessly. OK, cool. So assuming that we get beyond this point, then we could move on and delete the corresponding note. And I think this should do the trick. The final step is, well, where should we go at that point? Well, you've deleted the note. Maybe we should redirect you to the page that shows all of the notes. And in php, this is a little wonky, but we could add little helpers if we want to.
Maybe we should redirect you to the page that shows all of the notes. And in php, this is a little wonky, but we could add little helpers if we want to. In php, we're going to say header, and we're going to set the location to /notes. And then we're all done. So we can exit or die if you prefer. All right, so let's give it a shot. I will come back, give it a refresh. I will delete the notes. And sure enough, it's deleted and it redirected us back to this page. OK, but now let's come back and change the current userId to something like 25 or whatever.
And sure enough, it's deleted and it redirected us back to this page. OK, but now let's come back and change the current user ID to something like 25 or whatever. OK, well, now if the User with an ID of 25 tries to manually submit a request to delete this note, think about what happens. We first track down the note from the database. And that way, we can look at the person who created the note, the user ID. And if we check, well, that user ID is 1. And we check, all right, well, is 1 equal to the ID of the current user making the request? Does 1 equal 25? No.
So that seems to be working the way we'd want. OK, but yeah, now I just want you to take a look at the fact that we've created lots of branches here. Now, whenever I visit this page, it's not just the controller for showing a note. It's the controller for destroying a note or deleting a note. Here's a pathway for deleting it. Here's another pathway for showing it. And again, for small projects, it just doesn't matter very much because it's still relatively easy to understand. But you just don't want to build applications this way.
