So the general rule of thumb will be ādatabase normalizationā. This isnt really a Laravel concept, as it is a general database concept.
If every Admin has the same permissions, you dont want to store the permissions over and over in the table. Consider this: I want to store if someone has permission to modify 3 different pieces of data (A,B,C). I will call those permissions mA, mB, and mC.
I will have 3 users; Alice, Bob, and Charlie.
Bob and Charlie are my admins.
All admins can modify A,B, and C.
I could store them all in one table:
Name |
Email |
isAdmin |
mA |
mB |
mC |
Alice |
alice@example.com |
0 |
0 |
0 |
0 |
Bob |
bob@example.com |
1 |
1 |
1 |
1 |
Charlie |
charlie@example.com |
1 |
1 |
1 |
1 |
Butā¦ thereās not really much point in it, is there? If I know Bobās an admin, I already know he can modify A B and C because that was one of my rules. So I dont really need to store that information about him; i know heās an admin, so he has mA, mB, and mC. We could leave those three fields out of the database.
Name |
Email |
isAdmin |
Alice |
alice@example.com |
0 |
Bob |
bob@example.com |
1 |
Charlie |
charlie@example.com |
1 |
Great. Now i have stored all the information i need.
But maybe I make this configurable. Maybe the Super Admin can decideā¦ no, Admins shouldnt get mB.
Well i need to be able to change that somewhere where the system knows my rules have changed. So iāve definitely got to write mB in somewhere. But i dont really want to have to write in a 1 or a 0 for EVERY user, that uses up a lot of space if i haveā¦ a million users, and if the superadmin changes his mind later, i would have to update a million rows to make sure the change was made. That seems like a lot of effort.
So thatās why we do it in multiple tables.
Lets say the super admin has decided admins get mA and mC, but not mB.
I could write out a single table called Users:
Name |
Email |
isAdmin |
mA |
mB |
mC |
Alice |
alice@example.com |
0 |
0 |
0 |
0 |
Bob |
bob@example.com |
1 |
1 |
0 |
1 |
Charlie |
charlie@example.com |
1 |
1 |
0 |
1 |
SuperAdmin |
sa@example.com |
1 |
1 |
1 |
1 |
but thatās a lot of numbers. The information i want to store is āAdmins should have mA and mC, but not mBā. Notice i didnt mention Bob or Charlie by name there. The information I want to store is about the ROLE, not the individual USER.
So at this point, I need a new table. Roles. That way, I can have my role table (Note: Iām going to add an ID field here):
ID |
Name |
mA |
mB |
mC |
1 |
User |
0 |
0 |
0 |
2 |
Admin |
1 |
0 |
1 |
3 |
Super Admin |
1 |
1 |
1 |
Iāve now stored all the information about roles I need. And my User table can remain pretty simple:
Name |
Email |
Role |
Alice |
alice@example.com |
1 |
Bob |
bob@example.com |
2 |
Charlie |
charlie@example.com |
2 |
SuperAdmin |
sa@example.com |
3 |
A single number in the Role column tells me all i need to know.
So why does it suggest 3 tables to you?
What itās trying to do is create the idea of flexibility. If later on, you decide you want to add a new permission, youād have to modify the table, and the queries related to that table throughout the code, and etc.
If however, you make it āgenericā, you can more easily adapt your code.
What theyāre probably trying to suggest (I cant see your tutorial) is the idea of a Join table.
Namely:
- A User has a Role
- A Role may or may not have one or more permissions
- The list of permissions is not hard defined at time of creation, and/or may be added to by external items (addons, plugins, patches, etc).