Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

mrkarma4ya's avatar

Structuring code for different user roles

What would be the best way to structure code for when you have different roles?

For example, let's say I am building a website like Laracasts. I have 3 roles - Admin, Teachers and Students. I have a model 'Course' with can be indexed by all three roles. So admins get all courses, teachers get all courses they created and students get all courses that they subscribed to.

How do I structure code for this? Do I create 3 different controllers and 3 different routes for each role? Or do I create a single api/controller and just modify the query according to the role? If I were to use Laravel permissions by Spatie, how would I make use of it here? Is there any open source project which has similar features that I can learn from?

0 likes
1 reply
LaryAI's avatar
Level 58

One way to structure the code for different user roles is to use middleware to restrict access to certain routes or controller methods based on the user's role.

For example, you could create a middleware called "admin" that checks if the user is an admin before allowing access to certain routes or controller methods. Similarly, you could create middleware for teachers and students.

In terms of structuring the code for the "Course" model, you could use Laravel's built-in authorization features to define policies for each role. For example, you could create a "CoursePolicy" class with methods like "viewAny", "create", "update", and "delete" that define the rules for each role.

Here's an example of how you could structure the code for the "Course" model using middleware and policies:

  1. Create middleware for each role:
php artisan make:middleware AdminMiddleware
php artisan make:middleware TeacherMiddleware
php artisan make:middleware StudentMiddleware
  1. Define the middleware in your routes or controller methods:
Route::get('/courses', 'CourseController@index')->middleware('admin');
Route::get('/courses', 'CourseController@index')->middleware('teacher');
Route::get('/courses', 'CourseController@index')->middleware('student');
  1. Create a "CoursePolicy" class with methods for each role:
php artisan make:policy CoursePolicy
class CoursePolicy
{
    public function viewAny(User $user)
    {
        if ($user->isAdmin()) {
            return true;
        }

        if ($user->isTeacher()) {
            return true;
        }

        if ($user->isStudent()) {
            return true;
        }

        return false;
    }

    public function create(User $user)
    {
        if ($user->isAdmin()) {
            return true;
        }

        if ($user->isTeacher()) {
            return true;
        }

        return false;
    }

    public function update(User $user, Course $course)
    {
        if ($user->isAdmin()) {
            return true;
        }

        if ($user->isTeacher() && $course->teacher_id == $user->id) {
            return true;
        }

        return false;
    }

    public function delete(User $user, Course $course)
    {
        if ($user->isAdmin()) {
            return true;
        }

        if ($user->isTeacher() && $course->teacher_id == $user->id) {
            return true;
        }

        return false;
    }
}
  1. Use the "authorize" method in your controller methods to check if the user is authorized to perform the action:
class CourseController extends Controller
{
    public function index()
    {
        $this->authorize('viewAny', Course::class);

        // ...
    }

    public function create()
    {
        $this->authorize('create', Course::class);

        // ...
    }

    public function update(Course $course)
    {
        $this->authorize('update', $course);

        // ...
    }

    public function delete(Course $course)
    {
        $this->authorize('delete', $course);

        // ...
    }
}

This approach allows you to keep your code organized and maintainable, while also providing a clear separation of concerns between the different user roles.

Please or to participate in this conversation.