In my Symfony 2 application I want to use the standard Authorization system of users and roles (http://symfony.com/doc/2.0/book/security.html)
My User is an entity stored in a database with doctrine (implementing User Interface). I will have 5 predefined roles in my system, each user having possibly multiple of these roles.
What would be the most idiomatic way of implementing this? I am thinking of the following three solutions.
Make a separate Role entity and create a many-to-many relation with the user entity
Have a field within user that is a sorted, comma-seperated list of roles and getRoles() is implemented as explode(',',this.all_roles)
Have 5 binary fields in the user entity for each role
What is the most idiomatic way of implementing this system?
Of course an answer depens highly on your requirements, but I'll try to answer it as globally as possible.
Option 1: The relational way
From a pure relational point of view, you want your database normalized which would lead to your first option: A table for the roles with a m:n relation to your user table. This has some advantages:
Regarding your concern that roles never change: Storing data relational is not about how often it changes. And one should always remember that requirements change. The more you mess up right now in the name of optimization, the more you struggle later when there is the need for more roles which change more often.
Of course, you may have perfomance issues especially if you run into some kind of eager loading issue or if you don't cache things and have to reload roles on every page load. But than again, relational databases are designed to support such stuff, so here should be ways to optimize the queries.
Option 2: The hack
Your second option, simply storing all roles into a varchar, would be much nicer in terms of performance. Only one text field to load, some PHP processing and you are done. On the other hand, you may run into several issues:
Option 3: The pragmatic solution
The third option with 5 booleans for each role is in the middle: There is no way to screw it up and performance should not be a problem. Updating is easy as well as deleting a role or adding a new one. It's pretty clear what the fields do, so no harm on this side either. It makes your entity and database look a bit more ugly and you would have the role names in your user model as well to map the true/false fields to the correct role names, which might be a bit confusing.
Result
This all in mind, I would go with option 1. One may assume that performance is an issue, but unless I have prove of that, I don't think about such stuff. In the end, what do you do when you really have a real performance problem? You may add some additional hardware, optimize your dbms, optimize the queries or maybe use a dbms with more performance build in (Hello Oracle!).
And you can always use option 3 later on if you have prove that your application is slow because of the role table. You would just have to change your user entity and have one query which extracts the roles and sets the correct true/false combinations for every user. If the software is clean, this is an issue of hours, so no need to do it now on the idea that performance might be bad.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With