One of the new features in Laravel 5.8 allows you to not register your policies in AuthServiceProvider, they will be "guessed" automatically. Here's how it works.
Let's remember how Policies work in general.
Step 1: Create a policy with artisan command, attaching it to a model.
php artisan make:policy PostPolicy --model=Post
Step 2. Fill in the policy with exact methods and rules
use App\User;
use App\Post;
class PostPolicy
{
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
}
Step 3. Register policies (this is needed only before Laravel 5.8)
use App\Post;
use App\Policies\PostPolicy;
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
Post::class => PostPolicy::class,
];
So, from Laravel 5.8 you don't need to do step 3, system will recognize the policies automatically.
Here's how that "guessing" function actually looks in Laravel internals:
protected function guessPolicyName($class)
{
return dirname(str_replace('', '/', $class)).'\Policies'.class_basename($class).'Policy';
}
So your Policy should be in app/Policies folder and has the same name as model, with Policy suffix.
Correct location: app/User.php -> app/Policies/UserPolicy.php
Incorrect location: app/Models/User.php -> app/Policies/UserPolicy.php
Also incorrect: app/User.php -> app/Policies/UsersPolicy.php (Users)
And, also incorrect: app/User.php -> app/Policies/User.php (should be UserPolicy.php)
If your policies and models are in "nonconventional locations" (like not in app/ or app/Policies folders, as shown above), then you may use the same $policies array in AuthServiceProvider, or specify your own logic of "guessing":
Gate::guessPolicyNamesUsing(function ($class) {
// Do stuff
return $policyClass;
});
Here's a link to the original commit in Laravel.
No comments or questions yet...