Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here

Structure of Admin/User Role Areas

Premium
6 min read

In this lesson, let's talk about structuring projects by areas based on roles. It's a typical scenario for many projects: for example, you have administrator users and regular users.

There could be a more complicated scenario: for instance, in school management software, you might have students, teachers, admins, etc. So, how do we structure such projects?

We have two sub-questions I've seen developers asking:

  1. Do we define separate Models: app/Models/Admin.php, app/Models/User.php, etc?
  2. Do we define separate namespaces: app/Http/Controllers/User, app/Http/Controllers/Admin, etc? Same with Routes?

The answer to the first question is no. Please, please don't create separate models and DB tables for different user roles. It will bite you in the long run: you will need to repeat the same logic in multiple Models, then. Use one model User and then roles/permissions DB tables for this: below, you will see a few examples.

The second question can be answered with "it depends on a project" or "it's your personal preference".

Some projects have totally separate admin areas: different designs, different features, separate login areas, etc. Then, of course, it makes sense to separate the Controllers/routes/views into subfolders.

Other projects are just about checking the permission of the users to access the same pages/functionality. In those cases, I would go for the same folder for Controllers/routes/views and check the permissions as needed.

Let's look at examples of this approach from open-source projects.


Example 1. Check Roles/Permissions in Controller.

This approach to structuring admin/user areas is about using roles/permissions and not changing anything about the structure of the folders.

In other words, you have the same Controllers, common for...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (29 h 14 min)

You also get:

54 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

EV
Eugene van der Merwe ✓ Link copied!

Do we define separate Models: app/Models/Admin.php, app/Models/User.php, etc? Do we define separate namespaces: app/Http/Controllers/User, app/Http/Controllers/Admin, etc? Same with Routes?> The answer to the first question is no. Please, please don't create separate models and DB tables for different user roles. It will bite you in the long run: you will need to repeat the same logic in multiple Models, then. Use one model User and then roles/permissions DB tables for this: below, you will see a few examples.

I think that statement says it all. Having been bitten by a production project that is more than four years old I have learnt a lot through mistakes, but still have many lingering questions.

Let me make it clear I'm not worried about name spacing. Name spacing in my opinion is a more general / beginner type question.

  • My primary issue is if you have users that might have more than one role. Say for example there could be 2 or three roles and sometimes the user can belong to more than one role.
  • My secondary issue is the code bloat and SRP issues that suddenly appear in your user model, because you know, now this model applies to three different roles which all have three different requirements. I guess the quick answer here is use Traits, but I don't know?
  • My third problem is how to refactor? What if you have made this mistake, but you want to correct it? I guess automated testing is the first answer and search / replace the second one, but I am not sure.

Implementing multiple roles if you have a single database column doesn't suffice. It's back to many-to-many relationships either roll your own use Spatie's like so many people do.

The moment you have many-to-many filtering and a User database model it gets tricky.

Let's take this example for a video game.

Role #1 - Administrators - mostly administers the users but can also be a player. So more than one role.

Role #2 - Players

Role #3 Viewers. Only observes games and can like stuff. But can also be players. So again more than one role.

To design this more complex project there will be many hanging questions. Perhaps in your "Game" model there is a GameUser many to many and each line has a pivot column for "role" who created it?

Also, you probably can't have one dashboard. You have to carefully think about when a user with more than one role logs in, what to show them, how to direct them.

Then for your back office. Unless you like pain you're already using either Filament or Nova. In both Filament and Nova it's not so easy to generate resources for the same model but have them "separate". Elegant filtering is not so easy nor readable with many-to-many relationships. Performance might even suffer.

I would like to see a tutorial that handles the more complex cases as mentioned above starting with a user can have more than one roles, redirection, and how to elegancy build the admin back-end without breaking your back.

EV
Eugene van der Merwe ✓ Link copied!

After having type this huge reply I was wondering if you thought there was ever a use case for this:

Class Admin extends User

I've experimented with it and because of "authenticatable" it's not simple. But somehow I thought that to be a good solution, at one stage.

PK
Povilas Korop ✓ Link copied!

Wow Eugene, what a long comment. I appreciate you taking the time.

The thing is that your question touches on multiple topics that require multiple DEEP tutorials comparing the approaches. I will try to touch on them in my upcoming course about Roles/Permissions.

But, in short:

  1. Yes, for flexibility use many-to-many for roles/permissions (or Spatie package uses polymorphic)
  2. Whenever you can, avoid creating separate models for user roles. It makes life much more difficult later.

Everything else depends on the exact functionality you want to achieve for the exact project. The balance between performance, developer experience and user experience.

PK
Povilas Korop ✓ Link copied!

Also, one more thing I remembered: Spatie package docs say this, and I would apply it broader: don't be attached to roles, always check for PERMISSION (Gate) in your code, whichever roles have those permission.

A role is just a "parent" concept of "set of permissions", and roles may change quite a bit. But permission names rarely change.