Rails: Using CanCan to assign multiple roles to Users for each organization they belong to?
Asked Answered
S

2

6

A User can belong to many Organizations. I would like User to be able to be assigned different roles/authorizations for each of the organization it belongs to.

For example, user "kevin" may belong to organization "stackoverflow" and "facebook." kevin should be able to be an admin for stackoverflow, and a regular member(read+write) for facebook.

However, the CanCan gem only seems to address user roles for a single organization. I'm still a beginner, but from what I can gather, the CanCan gem assumes user roles are tied only to the main app.

How would I be able to assign separate roles for different organizations, preferably using the CanCan gem?

Shatter answered 21/2, 2013 at 7:10 Comment(0)
B
8

You're thinking that you have to save roles as a string field in the User model. You don't have to, at all:

class User
  has_many :roles
end

class Role
  belongs_to :user
  belongs_to :organization
  attr_accessible :level
end

class Ability
  def initialize(user)
    can :read, Organization
    can :manage, Organization do |organization|
      user.roles.where(organization_id:organization.id,level:'admin').length > 0
    end
    can :write, Organization do |organization|
      user.roles.where(organization_id:organization.id,level:'member').length > 0
    end
  end
end
Brinkley answered 21/2, 2013 at 8:0 Comment(1)
I've tried to apply this but I'm still having trouble. I would really appreciate help: #18483247Shatter
B
3

we have something like this. the solution is to override the current_ability method. in your case, you probably have a join table for users and organization. let's call that user_organizations. In this join table, you probably also store the user's role for a particular organization, right? So let's use that table to define the current ability. In your application controller

def current_ability
  # assuming you have a current_user and current_organization method
  Ability.new UserOrganization.where(user_id: current_user.id, organization_id: current_organization.id).first
end

# ability.rb
class Ability
  include CanCan::Ability
  def initialize(user_organization)
    user_organization ||= UserOrganization.new

    case user_organization.role
    when 'admin'
    when '...'
    when nil
      # for users not a member of the organization
    end
  end
end

hope this gives you some idea

Bethesde answered 21/2, 2013 at 7:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.