Need Role Blade Directive0:00
Inside of our Vues, we need to determine if a User is in a given role, and we can do that, of course, with the API that we have built. Our User model has the hasRole and the hasAnyRole methods, and, of course, we could use those. I don't want to, because that's a lot of typing, and we are going to be needing to check the roles in quite a few different places. So, instead, what I want to do is something like this, where we would have a role directive, and then we could simply supply the roles that we wanted to check for. But I don't want to do something like this, to where we'd have to pass in an array if we wanted to check for multiple roles, because I want to keep some consistency with our routes. You know, whenever we use the role middleware, we just supply a comma-separated list of roles that we wanted to check for. I want to do the same thing in our Vue, so that it would look something like this. We pass in just those strings, and that would get us essentially what we want. So, the first thing we need to do is head on over to our AppServiceProvider,
Register Custom Directives1:02
We pass in just those strings, and that would get us essentially what we want. So, the first thing we need to do is head on over to our AppServiceProvider, because we are going to create our custom directive there. Eventually, we'll get rid of the gates here, but I'm going to leave them so that we don't break anything just yet. So, we have Blade, we'll call the directive method, and we want our directive to simply be role. Now, I've gone back and forth on the name. Do I want to call it role, or do I want to call it roles? The key thing to me is that I want to be consistent between the directive and the method. I want to be consistent between the directive and the middleware alias. So, I'm just going to call it role, and if it's wrong, it's wrong. So, we'll have our role directive.
So, I'm just going to call it role, and if it's wrong, it's wrong. So, we'll have our role directive. Then we will have our closure that is going to have the expression passed to it. And all we really need to do is return an if statement. So, if we will use the auth facade so that we can get to the user. We'll call the hasAnyRole method, and then pass in the expression. Then we need a colon, and then we want to close out of that PHP tag. So, this is essentially how it works. Inside of our view, we use the role directive. Behind the scenes, Blade is going to take the return statement from our role directive, which is this right here.
Inside of our view, we use the role directive. Behind the scenes, Blade is going to take the return statement from our role directive, which is this right here. And it's going to place that directly inside of our view. So, for all intents and purposes, this @role admin is going to be replaced with this string here. That's how these directives work. So, then we also need to define the end role directive, which is just another call to the directive method. Except that this name is endrole, and all we need to do is specify endif here. And we don't need anything else. Well, we do. We need the closing tag there. So, that's all we need.
Fix Expression to Array3:02
Well, we do. We need the closing tag there. So, that's all we need. But before we do anything else, let's clear the view cache. And we will do so with php artisan view:clear. But whenever we view this in the browser, we can see that we have an issue. That the argument that is passed to hasAnyRole must be of type array. Well, that's easy enough to do. We can just surround our expression with square brackets. We need to clear the view cache once again. But now we can see that the $user's link is visible.
Test Single and Multiple Roles3:29
We need to clear the view cache once again. But now we can see that the user's link is visible. But we are, of course, signed in as an admin. So, let's sign out, and let's sign in as an author. And an author should not see the user's link. Sure enough, we don't. But let's change that. Let's just see if it's going to work if we pass in multiple values here. So, we'll pass in author. Back in the browser, we now see the user's link.
Apply Directive in Views3:54
So, we'll pass in author. Back in the browser, we now see the user's link. But, of course, if we try to access it, we get the 403 unauthorized. Because we prevent access using the middleware. So, that's perfect. Let's open up the index view for our articles. Because when it comes time to show that create link, I want only users who can create an article to see that link. So, that would be an admin as well as an author. Editors do not have that capability.
So, that would be an admin as well as an author. Editors do not have that capability. So, we will simply wrap that with our new role and end role directives. Let's be sure I took off the author for the User links. I didn't. So, we'll get rid of that. And so, now, whenever we view the articles, we should see the create link. But whenever we sign in with the editor, that link will not be available. We do, however, have the ability to edit any one of these articles. But whenever we sign back in with the author,
We do, however, have the ability to edit any one of these articles. But whenever we sign back in with the author, we can see that we can still edit the author's own articles. But we can't edit the author editor. And the reason is because we are still using that gate to show or hide the edit links. And that's something that we can't necessarily do with just roles. We can't determine whether we can show or hide these links based upon the roles themselves. So, the gate that we have defined for the manage articles, we will leave that for now. There's actually another way that we can approach that. But now we're going to run into another issue.
Reduce Role Query Overhead5:28
There's actually another way that we can approach that. But now we're going to run into another issue. Because every time we check for a user's roles, we hit the database. And that, of course, makes sense because, well, the role information is inside of the database. But at the same time, it doesn't make sense because all of these checks are within a single request. We hit the database at the route level. We need to check the roles then. Then we also check the roles multiple times inside of our views. So, that's a lot of database interactions. And I want to eliminate pretty much all of them.
So, that's a lot of database interactions. And I want to eliminate pretty much all of them. That's not possible, but we can at least limit it to one interaction. And we will do that in the next episode.
