I read here that in Laravel we can use the can
method instead of the traditional middleware call on a route. https://laravel.com/docs/11.x/authorization#middleware-actions-that-dont-require-models
use App\Models\Post;
Route::post('/post', function () {
// The current user may create posts...
})->can('create', Post::class);
Now the traditional method for middlewares looks like this:
Route::post('/post', function () {
// The current user may create posts...
})->middleware('can:create,App\Models\Post');
I really like this can
method and it would be nice to be able to replace middleware calls for update too to be consequent:
use App\Models\Post;
Route::put('/post/{post}', function (Post $post) {
// The current user may update the post...
})->middleware('can:update,post');
Is there a way to do this? The documentation does not contain anything about this...
There are few steps you need to follow.
Create & get registered your Policy
class.
With this command create a Policy-class. The generated policy will be placed
in the app/Policies
directory.
php artisan make:policy PostPolicy --model=Post
This class look like this.
namespace App\Policies;
use App\Models\Post;
use App\Models\User;
class PostPolicy
{
/**
* Determine whether the user can update the post.
*
* @param \App\Models\User $user
* @param \App\Models\Post $post
* @return mixed
*/
public function update(User $user, Post $post)
{
// Example: Only allow the user to update their own post
return $user->id === $post->user_id;
}
}
Then register the policy-class
to the boot
method of your application's AppServiceProvider
like this.
use App\Models\Post;
use App\Policies\PostPolicy;
use Illuminate\Support\Facades\Gate;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Gate::policy(Order::class, OrderPolicy::class);
}
And finally you can use the can
in the route to use this PostPolicy
class like this.
use App\Models\Post;
Route::put('/post/{post}', function (Post $post) {
// The current user may update the post...
})->can('update','post'); //here `post` is an instance of `App\Models\Post` model
N:B :-
Post
model must have a foreign-key
named user_id
upon which update
authorization will be matched.If no matched users found then an HTTP response with a 403 status will be returned.Policy
Generating Policies
& Registering Policies
section of the docs.