تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Add Edit Link0:00

Okay, let's work on editing and deleting Posts and also making sure that we have the correct authorization to perform those actions. So let's start off by adding an edit link here within myInfo, so we can edit our posts. So within myInfo, let's add another link here. After this one, let's copy this one here. Let's put a dot in between them. So ·, let's paste this one here. Let's make it go to /edit, and we'll add that route in a second. And let's make it say, edit. Okay, save that.

And let's make it say, edit. Okay, save that. That looks good. The mid dot did not render. I think there's two Ds. Okay. Let's go ahead and add this route here. So we want it to go to /edit. So we have to restructure our files here, because right now we have ID as a dynamic route right here.

Restructure Dynamic Routes0:49

So we have to restructure our files here, because right now we have ID as a dynamic route right here. So we need that to be a folder now. So let me rename this to index. We'll make a new folder, that's going to be the dynamic route, a new folder, [ID]. And now we can put the index in there. And we can add another one called edit in here. edit.vue Okay.

Edit .view. Okay. Let's just add a template here to make sure it works. And let's just say, edit. Let's see if the route param shows, route.params.id. Okay, we might have to restart the server here. Okay, let me refresh here. Let's make sure the original page still works. Does. Let's make sure edit works.

Build Edit Post Form1:38

Does. Let's make sure edit works. And it does. Cool. So edit is going to be similar to create. So let's go ahead and grab the code from there and make some changes. So let's go to create, let's grab everything here. Let's paste it in here. And let's make some changes. So after the errors, let's add a title for edit post, edit post, just make it a bit bigger.

And let's make some changes. So after the errors, let's add a title for editPost, editPost, just make it a bit bigger. So class equals text-xl. Let's change the method to updatePost. Let's change the button name to updatePost as well. So right here. And let's see if that renders. Okay, looks good. So now we need to grab the information for this post so we can display it in the title and the body here.

So now we need to grab the information for this Post so we can display it in the title and the body here. And we already have an endpoint for that. So it's the same endpoint as grabbing the Post and that should be public. So this endpoint right here, api/posts/{postId}. So let's grab this. And let's go ahead and do that. So back here to edit, let's make a new piece of state to hold our post here. So we'll add it right here. So say const post = ref(null); to start.

So we'll add it right here. So say const post equals ref, no to start. And I'm also going to import API fetch. So const API fetch from useNuxtApp. And then we can get rid of it here. Okay. Let's make a mounted hook and grab that information from our back end. So here we can say onMounted. It's a callback. Okay.

It's a callback. Okay. And it's pasted in that endpoint call. And we can assign it to the post directly here. So post.value equals await. So this has to be async. And we can say API fetch to that endpoint. Okay. And then when that's successful, we can assign the title here. So title.value equals post.value.title.

And then when that's successful, we can assign the title here. So title.value equals post.value.title. And same for the body. Okay, so let's see if this works. Hopefully it populates our form. And I'll wrap it in a try catch later on. Let's check out our form here. Let's refresh. And we are getting route is not defined. So we have to import that as well.

And we are getting route is not defined. So we have to import that as well. So same as this, but route instead of router. Okay. Let's try that again. Let me hide this. Let me refresh this. And there is our post. So now on our back end, we have to provide a route that allows us to update the post. So let's do that.

Add Update Endpoint4:10

So now on our back end, we have to provide a route that allows us to update the Post. So let's do that. Let's go to our back end here. Let's go to PostController. We can do it within the update method right here. Okay. And again, I'm just going to use the normal request here. And let's grab the validation from create up here. Let's paste it here. Okay.

Let's paste it here. Okay. And after that, we can just update the post. So I'm just going to return it here. post update. And let's update the title. So that's going to come in from the request. And the body as well. Okay. And I think this returns 1 if it's successful.

Okay. And I think this returns one if it's successful. If you want, you can return a proper JSON response. But this should be fine. So let's save that. Let's go to our API routes. And let's add a route for that as well. So we want to put it within this group here. So it's within the auth sanctum middleware. So let's duplicate this one.

So it's within the auth sanctum middleware. So let's duplicate this one. Let's make it a PATCH request. We can say post slash the post here. And we made it go to the update method. And again, we don't need a name here, but I'll just name it postPatch. Okay. Hopefully I did that right. Now we can wire it up to our front end. Let's go down here.

Now we can wire it up to our front end. Let's go down here. So the endpoint is /api/post/{id}. So we can grab that from the route. So let's say route.params.id. Okay. So that's going to be a PATCH request. Body is the same. We have our state for isLoading. We can set that to empty.

We have our state for isLoading. We can set that to empty. And let's say updatedPost. And let's just push back to the myInfo page. Okay. So save that. Hopefully I did everything correctly back to our app. Let me refresh this. Let me open up DevTools here. Go ahead and make some updates here.

Implement Delete Post6:24

It does. And it looks like it did update. So that is working correctly. So let's do the same for deletePost. I'm going to add a button within the edit page here that allows us to delete this post. Let me add it on the backend first. Should be pretty much the same as update back to our backend. Let's duplicate this route. It's going to be a DELETE request. The endpoint is the same.

It's going to be a delete request. The endpoint is the same. The method is going to be destroy. And let's name it post.destroy. Okay. And in our controller, let's go to destroy. We can just say post delete, or we can return that as well. Okay, let's save that. Let's go back to our frontend. And it's pretty much the same as this.

Let's go back to our frontend. And it's pretty much the same as this. But it's for deleting a Post. So let's copy this. Let's put it here. Actually, I don't think I copied the entire method. Let's make sure we do that. Duplicate it actually. Let's say deletePost. And the endpoint is the same.

Let's say delete post. And the endpoint is the same. It's a delete request. There's no body. That's fine. Let's say deleted post. We can push back to that page. Not to worry about errors here. And let's go ahead and add a button somewhere in our template up here. So I'll just put it after the form.

And let's go ahead and add a button somewhere in our template up here. So I'll just put it after the form. Let's just make it a button here, or I'll put it within a container. Button deletePost. And we can say addClick equals deletePost. Okay. Let's try that out. Back here. Let's refresh this page. Let's delete this post.

Let's refresh this page. Let's delete this Post. Okay. Deleted Post. And it looks like it's still here. Maybe if I refresh. And of course it's not working because this should be a method. So let's try that one more time. Let's try deleting this Post.

Enforce Post Authorization8:21

Let's try deleting this post. Delete post. And now it's gone. Cool. Now let's work on authorization to make sure Users can only delete their own posts. So right now, if I were to go to this edit page, this is our Post, but I could easily just change the URL here and go to someone else's Post. So for example, if we go into the database, you'll see that Post 25 does not belong to me, but we can still edit it. So we can say 25.

me, but we can still edit it. So we can say 25. Let's change this and it should still work. And you can see in the database, it did update. So let's add some authorization to make sure that doesn't happen. So into our backend, I'm going to make use of policies here. And there should be a PostPolicy that was created when I did model:all. Okay, there it is. And there should be an update method in here that we can make use of. And you can see it determines whether the User can update the model.

And there should be an update method in here that we can make use of. And you can see it determines whether the loggedInUser can update the model. So it's going to pass in the loggedInUser here. And we just have to do a check here. So return the loggedInUser is equal to the person who posted the post. So we can say postUserId. Okay, and I'm just going to cast it to an int just to make sure sometimes it's returned as a string. So let's just say int. And for here as well.

So let's just say int. And for here as well. Okay. And I'm going to do the same for delete as well. So down here, there should be a delete method. Or you can just make use of this if it's the same rule. But I'm just going to duplicate one for delete, even though it's the same rule. So let's save that. And now let's go back to our app and go back to the form for a Post that does not belong to us.

And now let's go back to our app and go back to the form for a Post that does not belong to us. So that was post 25. So let's go to that again. 25. Okay. And let's make sure to make use of that policy. So back to Laravel, there are several ways to do this, but I'm going to do it in the PostsController.

controller. So PostController. So for updating, we can make use of the authorize method. So we can say $this->authorize, and we want to make sure the logged in user is able to update this post. So that method we just created in the policy, and we'll pass through the post here. So let's add the same for delete, but for delete, obviously, so down here, let's change it to delete. Okay. And now these actions should be protected, and only the user who created the post should

Okay. And now these actions should be protected, and only the User who created the Post should be able to update or delete the Post. So back here to our app, let's refresh. If I were to try this, let me open up the network tab here, we should get a 403 unauthorized response. So let's try updating. There it is 403, unauthorized, and same for deleting. There we go, cool. And you can respond however you like in your front end.

There we go, cool. And you can respond however you like in your front end. So say, for example, let's go back to our front end here for updating post. Right here, we can say if error.response.status, we can grab the 403 status, and then we can do whatever we want in here. So let's just early return and let's just alert the error.data.message. Okay, let's try that again. Let's refresh. Let's try updating. And we do get that alert.

Let's try updating. And we do get that alert. Now let's make sure that the User can even hit this page if they don't have proper authorization. So if you remember, we grabbed the post up here in the mounted hook. And this endpoint is public, because it's just grabbing the post information. So what I'm going to do is make another route here on the back end, that's pretty much the same as this, but has authorization in place. So if the currently logged in User should not be able to access this route, then we can catch that error and redirect accordingly. So I'm going to name it postsOff.

can catch that error and redirect accordingly. So I'm going to name it posts. Let's go ahead and try catch this now because it should return an error if the user does not have authorization. So try this, catch the error. And if there is an error, and you can be more specific if you want to catch the unauthorized error, but I'm just going to redirect here. And you can either use the router or I'm just going to do a full page redirect here. So window.location.pathname, and I'll just redirect back to the homepage. Okay, so let's add this on the back end, before I save actually.

Okay. Sorry, that's not what I meant. I meant this route here. Let's grab this, put it here. And let's make it go to the edit method here. And let's make sure to change the name. So postAuth, or postsAuth, and let's say postEdit. Okay, let's go to PostController here. And like I said, it's pretty much the same as this one right here. So let's grab this.

And like I said, it's pretty much the same as this one right here. So let's grab this. But we're going to put authorization in place. So we can use that same method here. And I'll just use the update method in our policy. Okay, so let's save this. Hopefully I did that right. I think we have to save the front end as well. Let's save this, go back to our front end. And you can see it did redirect back to the homepage because this post does not belong

Let's save this, go back to our front end. And you can see it did redirect back to the homepage because this post does not belong to the logged in user. So let's try that again. So these posts should be fine because we did create them. So edit should work the same way. Let's double check. Okay. But if we try to go to a post that we didn't create, forgot the ID, 25, then it should just redirect back to the homepage.

But if we try to go to a Post that we didn't create, forgot the ID, 25, then it should just redirect back to the homepage. And it does, cool. So yeah, that's pretty much it. We should now have proper authorization within our application. So as always, let's go ahead and make commits. This is the back end. So let's say git add, git commit authorization. And for the front end, git add, git commit, say authorization for edit and delete posts.

And for the front end, git add, git commit, say authorization for edit and delete Posts.

Policies in LaravelEnsure policies work on frontend

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟