A gate is a closure that returns true|false. A policy is a class of gates scoped to a model.
Gates (one-off)
// app/Providers/AppServiceProvider.php
Gate::define('access-admin', fn (User $user) => $user->is_admin);
// Anywhere:
if (Gate::allows('access-admin')) { … }
Policies (per-model)
php artisan make:policy PostPolicy --model=Post
class PostPolicy
{
public function update(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}
}
Wire it up via AuthServiceProvider::$policies, then:
public function update(Request $r, Post $post)
{
$this->authorize('update', $post); // throws 403 if not allowed
$post->update($r->validated());
}
In Blade: @can('update', $post) … @endcan.
On routes: ->middleware('can:update,post').