Rails CanCanCan基于部门的资源能力

时间:2019-02-04 18:43:28

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2 cancan cancancan

我有两种用户类型:管理员普通用户

我有以下部门

  • 前台(例如,id为1)
  • 后台办公(例如,id为2)
  • 管理员(例如,id为3)

我有一个名为 Entry 的模型,该模型需要 user_id,department_id,customer_id

管理员用户对所有部门和所有条目

具有完全控制CRUD

普通用户是为相应部门创建的,并且对相应部门的条目具有CRU控制权

当我从普通用户(例如,id为2)帐户创建条目时,我得到了正确的 customer_id,department_id,user_id 设置表中的em>。该用户的权限只有一个条目can_create_entry(current_user.id,customer_id,department_id),例如,(1,1,2)用于前台普通用户帐户。

当我从管理员(例如,id为1)帐户创建条目时,我得到的customer_id,department_id,user_id为(1,1,1)在表wen中,我尝试为ID为2的后台部门创建一个条目。

当我查看 Admin 用户的功能列表时;我发现条目功能重复,即。

#<CanCan::Rule:0x0000000b61fd18 @match_all=false, @base_behavior=true, @actions=[:create], @subjects=[Entry(Table doesn't exist)], @conditions={:user_id=>1, :customer_id=>2, :department_id=>1}, @block=nil>

#<CanCan::Rule:0x0000000b61fd18 @match_all=false, @base_behavior=true, @actions=[:create], @subjects=[Entry(Table doesn't exist)], @conditions={:user_id=>1, :customer_id=>2, :department_id=>2}, @block=nil>

#<CanCan::Rule:0x0000000b61fd18 @match_all=false, @base_behavior=true, @actions=[:create], @subjects=[Entry(Table doesn't exist)], @conditions={:user_id=>1, :customer_id=>2, :department_id=>3}, @block=nil>

对于普通用户,我只有一个条目

#<CanCan::Rule:0x0000000b61fd18 @match_all=false, @base_behavior=true, @actions=[:create], @subjects=[Entry(Table doesn't exist)], @conditions={:user_id=>2, :customer_id=>2, :department_id=>1}, @block=nil>

请帮助我解决管理员角色的问题。

已编辑: ability_base.rb

class AbilityBase
  include CanCan::Ability
  ...
  def can_read_entries(customer_id, department_id)
    can :read, Entry, :customer_id => customer_id, :department_id => department_id
  end

  def can_create_entries(customer_id, department_id,user_id)
    can :create, Entry, :customer_id => customer_id, :department_id => department_id, :user_id => user_id
  end

  def can_update_entries(customer_id, department_id, user_id)
    can :update, Entry, :customer_id => customer_id, :department_id => department_id, :user_id => user_id
  end

  def can_destroy_entries(customer_id, department_id)
    can :destroy, Entry, :customer_id => customer_id, :department_id => department_id
  end
  ...
end

user_ability.rb

class UserAbility < AbilityBase
  def initialize(current_user)
    if current_user
       user_department_type_names = {}
       @customer = current_user.customer
       @user_type = current_user.user_type
       current_user_dept = current_user.departments           
       @user_department_ids = current_user_dept.collect(&:id)
       @user_department_type_ids = current_user_dept.collect { |dept| 
          dept_type = dept.department_type
          user_department_type_names["#{dept_type.type_name}"] = dept.id
          dept_type.id
       }
       ...
       if user_department_type_names.has_key?("FRONT_OFFICE")
         dept_id = user_department_type_names["FRONT_OFFICE"]
         if @user_type == "NORMAL_USER"
            can_read_entries(customer.id, dept_id)
            can_create_entries(customer.id, dept_id, user_id)
            can_update_entries(customer.id, dept_id, user_id)
         elsif @user_type == "ADMIN"
            can_read_entries(customer.id, dept_id)
            can_create_entries(customer.id, dept_id, user_id)
            can_update_entries(customer.id, dept_id, user_id)
            can_destroy_entries(customer.id, dept_id)
         end
       elsif user_department_type_names.has_key?("BACK_OFFICE")
         dept_id = user_department_type_names["BACK_OFFICE"]
         if @user_type == "NORMAL_USER"
            can_read_entries(customer.id, dept_id)
            can_create_entries(customer.id, dept_id, user_id)
            can_update_entries(customer.id, dept_id, user_id)
         elsif @user_type == "ADMIN"
            can_read_entries(customer.id, dept_id)
            can_create_entries(customer.id, dept_id, user_id)
            can_update_entries(customer.id, dept_id, user_id)
            can_destroy_entries(customer.id, dept_id)
         end
       elsif user_department_type_names.has_key?("ADMIN")
         dept_id = user_department_type_names["ADMIN"]
         if @user_type == "NORMAL_USER"
            can_read_entries(customer.id, dept_id)
            can_create_entries(customer.id, dept_id, user_id)
            can_update_entries(customer.id, dept_id, user_id)
         elsif @user_type == "ADMIN"
            can_read_entries(customer.id, dept_id)
            can_create_entries(customer.id, dept_id, user_id)
            can_update_entries(customer.id, dept_id, user_id)
            can_destroy_entries(customer.id, dept_id)
         end
       end
       ...
    end
  end
end

1 个答案:

答案 0 :(得分:0)

我为此使用了一些不同的方法:

class UserAbility
  include CanCan::Ability

attr_accessor :user

def initialize(user)

@user = user

can :read, Entry, do |entry|
  is_admin || (is_normal_user && Entry.where(id, entry.id, customer_id: @user.customer_id, dept_id: user.departments.ids).exists?
end

private

def is_normal_user
  user.user_type == 'NORMAL_USER'.freeze
end

def is_admin
  user.user_type == 'ADMIN'.freeze
end

end

当然这只是一个模板