Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Події
Інше
Про нас

Як влаштувати ролі та права, коли Gate вже замало?

Починається все з простого $user->is_admin, далі зʼявляється редактор, потім модератор - і умови розповзаються по коду.

Крок перший - роль як enum:

enum Role: string
{
    case Admin = 'admin';
    case Editor = 'editor';
    case Author = 'author';
}

Це вже краще за рядки, але перевірки виду $user->role === Role::Editor розкидані по контролерах ламаються, щойно права ролі змінюються.

Крок другий - права, а не ролі. Код питає «чи можна публікувати», а не «чи ти редактор»:

Gate::define('publish', fn (User $user) => $user->hasPermission('publish'));

Роль стає лише набором прав, і зміна набору не потребує правок у коді.

Policy для дій над моделлю:

class PostPolicy
{
    public function update(User $user, Post $post): bool
    {
        return $user->hasPermission('posts.update')
            || $post->author_id === $user->id;
    }
}

before() для суперкористувача - щоб не дублювати перевірку в кожному методі:

public function before(User $user): ?bool
{
    return $user->isAdmin() ? true : null;
}

Повертати треба саме null, а не false: false заборонить дію остаточно й не дасть іншим методам відпрацювати.

Коли брати пакет. spatie/laravel-permission дає ролі, права й кеш перевірок з коробки. Він доречний, коли набір прав змінюють з адмінки; якщо ролей три й вони зашиті в код, enum із Policy простіший.

Що не забути: перевірки прав кешуються не самі - на кожен запит це кілька звернень до бази, тому права користувача варто завантажувати разом із ним.

Докладніше в документації: Авторизація

Схожі питання