Updating Author Store Method0:00
We are primarily finished with the TicketController. Now we need to focus on the Author's TicketController, because the functionality is relatively the same. There's just a few differences. So we're going to start with the store method, because I think that this is probably where the majority of our changes are going to be. And the first change is I'm going to reorder these parameters to be consistent with everything else. Because if we look at the replace method and the update, the request object is the first parameter, and it wasn't in that case.
Because if we look at the replace method and the update, the request object is the first parameter, and it wasn't in that case. So that is done. And I think the majority of our changes are going to be inside of the StoreTicketRequest. Because if we take a look at the request itself, the authorId is now part of the URL, so it doesn't really make much sense to include that with the request. Although we could make the argument that in order to be completely consistent, yes, we need to include it with the request. But I don't think that we really need to do that. Because we are dealing with a resource for a given User.
But I don't think that we really need to do that. Because we are dealing with a resource for a given User. We already have that User. So let's do this. We will keep our rules the same, except that now we don't really need to check what the route is. Because it doesn't matter what the route is. If we have just a typical User, they should only be able to create their own tickets and not create a ticket for someone else. So now we would just have that check for create own ticket.
not create a ticket for someone else. So now we would just have that check for create own ticket. If so, then we make sure that the userId is part of that validation rule, and we're good to go. But now let's override the prepareForValidation. The authorId is now going to be part of the URL. So what we will do is check to see what the route is. And if it is authors.tickets.store, then we will merge in the authorId. So this should work. We'll take the data relationships authorDataId, and we will set that to the data that
So this should work. We'll take the data relationships author data id, and we will set that to the data that was provided in the route. And that was simply just author. So that should be good as far as that is concerned. Which means that now inside of our AuthorTicketsController, we just need to copy the code from our store method from the TicketController. And I don't really think we need to make many changes here. So let's copy that, but that's the wrong method. Let's go to the store method.
So let's copy that, but that's the wrong method. Let's go to the store method. Let's copy that code. Let's paste it inside of the store method. And let's see about this. So our policy should be the same. We will attempt to create a new Ticket with the mapped attributes, but that is going to be an issue because our mapped attributes is only going to iterate over the attributes from the JSON structure. Now we need to also include anything that, well, that we might need.
Extending Mapped Attributes2:58
from the JSON structure. Now we need to also include anything that, well, that we might need. In this case, it would be a parameter from the route. So what if we did something like this to where we still call mapped routes, but we could supply an additional attribute if we needed to. So we could say that we have this author that's part of the request, and we want to map that to user ID. So that means inside of our BaseTicketRequest, we can accept an array called otherAttributes. We can initialize it as an empty array, but then we can merge these two arrays together to where the first array is our normal array that we've been using with the JSON structure.
We can initialize it as an empty array, but then we can merge these two arrays together to where the first array is our normal array that we've been using with the JSON structure attributes with the Ticket model attributes, and then we merge in any other attributes. That way, anything that we supply as an argument would override anything from the original attribute map. And I think that that's perfect. So let's leave that as is. And that should be enough for our store method. Yeah, I think everything else would be fine. So let's move on to the replace method.
Simplifying Replace Logic4:03
Yeah, I think everything else would be fine. So let's move on to the replace method. So here we are fetching the ticket with a given ID. We are checking if that ticket userID is the same as the authorID. And I don't know why I did it this way. Because really what we should have done is this, to where the ID of the ticket is going to be the same as the ticketID, and then we'll also where the userID is the provided authorID. Then we will call firstOrFail. That's a whole lot simpler.
Then we will call firstOrFail. That's a whole lot simpler. So we no longer have to check the user IDs. Everything else should be fine. Now as far as mapped attributes, everything should be okay here because this is the replace request and that is for the put. So if we are going to replace a resource, the request should include all of the information for that resource. So yeah, we don't need to change anything as far as the mapped attributes are concerned. The only thing we need to do is check our policy.
So yeah, we don't need to change anything as far as the mapped attributes are concerned. The only thing we need to do is check our policy. So we'll say isAble the ReplacePolicy and then we will pass in the ticket. Now let's do check that policy. However, we also need to set the policy class, don't we? So from our TicketController, we will copy that line of code so that we can add that protected policy class. And now let's take a look at our ReplacePolicy. So here, yes. If the user can replace the ticket, then great, except that we really should have just done
So here, yes. If the User can replace the ticket, then great, except that we really should have just done that. That would have been a lot simpler. So there we go. Nice and clean there. All right. So we are done with our store ticket requests. Our replace method, we are fetching the ticket. If it doesn't exist, then the model is not found.
Our replace method, we are fetching the ticket. If it doesn't exist, then the model is not found. We check the policy, we update, and then we return the newly updated ticket. So that's great. Let's go ahead and let's copy, though, this authorization exception. And we need to change the text here. You are not authorized to create that resource. For replace, that text should be fine. You are not authorized to update that resource. And then we have the update method, which is going to be very similar.
Updating Patch and Destroy6:18
You are not authorized to update that resource. And then we have the update method, which is going to be very similar. Let's grab this new code to where we fetch the ticket based upon the ID and the user ID. That way, we don't have to check those IDs anymore. The update method, mapped attributes, let's take a look at the request. So for a patch, the client needs to supply whatever attributes that they want to update. So if they want to update it, they need to include it. We don't need to have any other mapped attributes. We do, however, need to check our policy.
We don't need to have any other mapped attributes. We do, however, need to check our policy. So that is the updatePolicy and the provided ticket. But let's check the updatePolicy. And yes, if the User can update the ticket, then true. If they can update their own ticket, then we check the userIds. Yeah, that's fine there. So we will update, return the newly updated resource. And that should be that. Let's once again copy this catch for the AuthorizationException.
And that should be that. Let's once again copy this catch for the AuthorizationException. And let's move on to the destroy method. Once again, why did I think that this was a good idea? This just goes to show, code that we write, even though it does work, might not necessarily be the best thing. And it's okay, we can always go back, we can make changes. And I can't tell you how many times I've gone back to old code and I've thought, what in the world was I thinking? I could have done this much simpler, and this is just one of those times.
I've thought, what in the world was I thinking? I could have done this much simpler, and this is just one of those times. So we fetch that ticket, we need to check our policy. And yeah, there's nothing to update, so we don't need to map anything. We don't need to validate anything. Yeah, everything should be fine there. We do need to, once again, catch that Authorization exception so that we can say that you're not authorized to delete that resource. But just to be thorough, let's check our delete policy. And yep, everything is okay there.
Testing and Fixing Validation8:14
But just to be thorough, let's check our delete policy. And yep, everything is okay there. So now let's do some tests. So let's start with our POST request. And we are signed in with the User with an ID of 1. So let's try to create a new ticket for the User with an ID of 2. We should get our validation response. That is not the validation response that I was expecting. Data relationships author data ID field is required. Well, I would have thought that, yeah, we included that.
Data relationships author data ID field is required. Well, I would have thought that, yeah, we included that. So let's go to the tickets.store, that's obviously not working. So let's do this. Let's say that we are going to have our authorID attribute. And this is going to change based upon the route. So if the route is tickets.store, then the ID is going to be what we expect from the JSON structure. Otherwise, it's going to be simply author.
then the ID is going to be what we expect from the JSON structure. Otherwise, it's going to be simply author. All right, so let's copy this so that we can put that there. Then we will say that the authorID attribute is going to be used here. And we need to update that same rule there. And then we will change this to simply author. And so now let's see if that's going to work. We should hopefully get our yes, the author field must be one. So that's perfect. So let's now try to create this.
So that's perfect. So let's now try to create this. We have a new ticket. This is another ticket. Okay, let's send that request. We can see that that was indeed created just as a sanity check. Let's try to create a normal ticket from our TicketsController. And we'll just have some text here. It doesn't matter what it is, but we will create that. Sure enough, that was created.
It doesn't matter what it is, but we will create that. Sure enough, that was created. Let's try to create it for the User with an ID of two. We should get our validation error, and we do. Okay, so POST request works fine. The PUT request, we can't test with this User, but it should be fine. Let's do the PATCH request. And I think we have the ticket with an ID of two. So let's try to change that. We will send that request.
So let's try to change that. We will send that request. Looks like that that worked. But let's try for a ticket that doesn't belong to this User, and Ticket cannot be found. So that's okay, that's good. And now we just need to delete one. And let's delete, let's see, whatever Ticket that we just created, ID of 105. Let's first of all, try to delete a Ticket that doesn't belong to this User.
whatever ticket that we just created, ID of 105. Let's first of all, try to delete a ticket that doesn't belong to this user. So we see that the, okay, that's, wait, yeah, that was right. Okay, so it works, and that works too. So I deleted the ticket with an ID of 2, which is unfortunate because that was easy enough to remember, but obviously not easy enough to remember that that was not the one that I needed to update. Okay, so there we go. We have implemented our TicketController and the AuthorTicketsController.
Transition to User Management11:19
Okay, so there we go. We have implemented our TicketController and the AuthorTicketsController. So we can now focus on implementing our User management.
