4

So I'm making a bug tracker to help me learn Ruby on Rails. My current setup is something like this:

  1. Each Project has_many :metadata and has_many :permissions, through: :metadata. Also some other stuff, but that's all that's relevant to this question.
  2. Each Metadatum (bad name, I know, but it'll work for now) has_many :permissions, and belongs_to both :project and :person.
  3. Each Permission belongs_to :metadatum, and both has_one :project, through: :metadatum and has_one :person, through: :metadatum. It represents one person being able to do one thing on one project -- for example, add a new bug, or assign someone to a bug, etc. etc.

Now, my question is if this is a good way to go about adding different levels of permission that are different for each project -- so, for example, Project Manager Eve can't edit Project Manager Bob's projects just because she's a PM too, and QA James can't add lots of bugs to a project he isn't supposed to be testing.

It makes sense to me because each project has metadata that applies to everyone (which is stored in Project) and individual metadata for each person (which is in Metadatum and includes stuff like if they've starred it or if they've assigned it a custom name). To me, it's sensible that Metadatum would also store the permission level, since that's dependent on the project and person both.

However, I'm concerned about space usage, though I don't know if I should be. It would be fairly trivial to change it to use some bitmasking magic to do the same thing, but my concern about that is that it's less readable, and only allows a certain amount of permissions to be added before running out of room in a number. I'm also concerned that it'll take longer to check if someone is allowed to do something than bitmasking, because instead of permission & 1<<12 you have to check project.permissions.find_by(person: person, allows: :allowance), which involves filtering twice, and isn't as readable. However, it's conceptually simpler to understand, and custom methods could easily be written to simplify the syntax.

Have I got the best approach? How can I do it better?

4

Now, my question is if this is a good way to go about adding different levels of permission that are different for each project

It's an okay start, but will suffer if used with a larger number of users. Permissions management is best handled through groups. So the Dev_Group is allowed Permissions A, B, C and the IT_Admin_Group is allowed permissions C, and D on the same Project.

The benefit here is that when Ishmael leaves the project, he's simply removed from the IT_Admin_Group. And when Helena joins the team then she's added to the Dev_Group. All of the necessary permissions are then automatically revoked or applied as the circumstances dictate. Group management of permissions helps avoid the problem of accidentally forgetting to update an area. And on large projects, that happens quite frequently when individual permissions are used instead of group permissions.

You can still use individual permissions to override the group settings if you'd like. So if Helena was in a probationary period after joining, she may have Dev_Group permissions to A, B, C but an individual override to remove C.

However, I'm concerned about space usage, though I don't know if I should be.

At this stage in the development of your project, you shouldn't be worried about it. Err on the side of readability and ease of maintenance above all else. If / when this grows into a reasonably large project, you'll thank yourself a million times over when you have to maintain a section of code that you haven't touched in 6 months.

Likewise, in most environments where this would be used, memory utilization for permissions is not going to be a constraining factor.

I'm also concerned that it'll take longer to check if someone is allowed to do something than bit masking

Again, err on the side of readability and ease of maintenance. If you do a proper job of encapsulating the implementation of the permissions checks then you'll be able to more easily refactor that section to a different approach when circumstances dictate a refactoring is necessary. Said more clearly, permissions checks in a typical environment are not going to be your constraining factor for performance purposes.

Overall, your focus should be on getting the project to a working state so you're able to achieve the learning goals you wanted. And while it's good to keep an eye on these considerations, getting it working is more important. Once you've written a complete unit test suite for it, then you'll be able to more easily go in and refactor the sections that are still bothering you.

| improve this answer | |
  • "Permissions management is best handled through groups" So, if I understand what you're saying, each Project has_many :groups, and each Group has_many :permissions, then make a join table/has_and_belongs_to_many to associate people with groups. Does that sound right? – Fund Monica's Lawsuit Dec 23 '15 at 13:39
  • @QPaysTaxes - yes, that's a fairly standard implementation of it. – user53019 Dec 23 '15 at 14:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.