I was implementing authorization policies in my Laravel app for determining what users can do what actions. As stated in the documentation, if you want to check a policy, you can do something like this in the controller:
if (Gate::denies('update', $post)) {
abort(403);
}
}
Then Laravel knows that $post
is an instance of the Post
class and can check the policies for that class. But what if we don't have an instance of $post
available for indicating Laravel what policy should it check, since we are for example, about to create a post?
Well, I had to search in the framework code for getting a response to this question, in Illuminate/Auth/Access/Gate.php
there is the following function:
protected function firstArgumentCorrespondsToPolicy(array $arguments)
{
if (! isset($arguments[0])) {
return false;
}
if (is_object($arguments[0])) {
return isset($this->policies[get_class($arguments[0])]);
}
return is_string($arguments[0]) && isset($this->policies[$arguments[0]]);
}
In the last line we can see that we can also pass a string to the denies
function to determine what policy do we want. So we can call the function using a string referring to the model like this:
if (Gate::denies('create', 'App/Post')) {
abort(403);
}
}
And then when defining the policy, there is no need to use a second parameter for referring to the model instance, so it will look like this:
public function create(User $user) {
return [..] //Whatever condition you want
}
Hopes you find this helpful, see you!