Reputation: 2704
For Rails I see quite a few gem options for role-based access control (cancan, cantango, etc.) However, I'm not finding any gems for group-membership-based access control. Here is a simplified description of what I'm trying to accomplish:
Users: a, b, c, d
Groups: y, z
Group Membership: y has a and b; z has c and d
Posts: m, n
Ownership: a owns m; c owns n
Group y is marked as a public group. m can be seen by all users
Group z is marked as a private group. n can only be seen by c and d
So nothing too fancy or complex, essentially a capability similar to file system access control (e.g. read-write-execute across owner-group-public [without the 'execute' of course].)
It looks like Radiant (with some extra plug-ins) can provide page-level group-membership access control, but I don't want/need a whole CMS and I would prefer something that is model-based (like cancan) vs. page/path based. (BTW, I'm using Devise for my user model - is there something in Devise I missed?)
How are private/public user groupings implemented in Rails? Only through a Rails-based CMS? Am I missing something basic? Or is this use-case rarely tackled in the Rails community?
Upvotes: 0
Views: 948
Reputation: 2704
I found the answer for this and thought I would post it in case anyone else is looking for it.
CanCan does support group capability via "Hash of Conditions". The idea is that post
is tagged with a :group_id
(belongs_to
a group
) and users
has_many
groups
. Then you can set up the "hash of conditions" within the can
statement as follows:
can :manage, Post, :group => { :id => user.group_ids }
The "hash of conditions" is documented further here:
https://github.com/ryanb/cancan/wiki/Defining-Abilities
Thanks to @Jason_Noble for pointing me back to the cancan docs where I finally found it.
p.s. one implementation note. If you wish to have some Posts public and some Posts private, you can set up a default group of which each user is a member. All public Posts should then be tagged with the default group_id.
Upvotes: 1
Reputation: 3766
I would use CanCan and do something like:
can :view_post, User if user.is_member_of_group?(z)
Upvotes: 0