Hacker News new | ask | show | jobs
by dpeck 4468 days ago
related, Pundit provides some similar functionality in a very minimal package https://github.com/elabs/pundit
2 comments

We've been using Pundit with great success in our organization. We use it along with a few other objects described below.

We have abilities, which is just a table full of strings like "modify users". The policy (from Pundit) looks these up to find whether an actor (user, typically) can do something to a model.

We have roles, which is just a user-definable collection of abilities, so you might define an 'admin' role that has every permission, and a 'reporter' role that has the ability to run reports and not much else.

We have permissions, which includes a role, a manager, and a manageable. The manager is the actor, or the thing asking to do something to another object; the managable is the object the actor is trying to act upon.

There is a "Managable" concern that gets included in any object that may be guarded by policies, and a "Manager" concern that gets added to any object that might be an actor. The Manager concern sets up the associations gives us methods like "#has_ability_on(ability, managable)", and "#has_ability)", which is useful for deciding whether to show gui widgets. These methods are how Pundit looks up the abilities one (manager) object has on another (managable) object.

This simple setup has allowed us to greatly simplify our application.

Curious is you have some more details about this written up anywhere or some code on github?

I'm just using Pundit in a "real" app for the first time where strict user types won't be enough and I need to have a role based approach. I'm doing something similar to what you have now, but a couple steps back in my design process, and the managable concern sounds promising.

That would be a good idea for a writeup. I'll have to get that done. For now, I have a couple more details.

We're using the closure_tree gem to give a hierarchy to the permissions; every permission can have a parent, which may further limit which abilities are allowed on a managable by a manager. This means that if user A has abilities "1,2,3" on an object, when he grants a permission to user B, while he can create the permission with whatever abilities he wants (maybe abilities "2,3,4"), the parent of that user B's permission is user A's permission, which restricts the real abilities user B has so that user B effectively has only abilities "2,3" on that object. To do this, we get the whole ancestor chain and take the intersection of all the abilities of each permission.

We also have organization objects; these are the owners of everything in the system - they own the users, the roles, the permissions, etc. Organizations may also be a manager or a managable; in fact, an organization automatically gets a permission with itself as both the manger and the managable, with every ability. We also use closure_tree with organizations: when an organization is the managable part of a permission, that permission applies to everything the organization owns, including all descendants.

So we have permissions with a hierarchy where we look upward at its ancestors to limit its abilities, and organizations with a hierarchy where we look down to find the scope that permission operates on.

awesome. I'd definitely like to see a full writeup if you ever do one, email is in my profile.
We use pundit more often these days to cancan, I would recommend it.
agreed, it seems like the way to go today. But there has been some movement towards reviving cancan lately https://mojolingo.com/blog/2014/putting-the-can-in-cancan/ so we'll see where it goes.