Rails的基于部门CanCanCan资源的能力

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rails的基于部门CanCanCan资源的能力相关的知识,希望对你有一定的参考价值。

我有两个用户类型管理员和普通用户

我有以下部门

  • 前厅(例如,ID为1)
  • 后台(例如,ID为2)
  • 管理员(例如,ID为3)

我有一个模型一个名为Entry这需要USER_ID,部门标识,CUSTOMER_ID

Admin用户拥有所有部门和所有项目的完全控制CRUD

普通用户是针对各个科室创建和拥有各自部门的项目CRU控制

当我创建一个从普通用户的条目(例如,ID为2)帐户,我得到了正确的设置CUSTOMER_ID,部门标识,USER_ID的表中。该用户的能力只有一个条目can_create_entry(current_user.id,CUSTOMER_ID,部门标识),例如,(1,1,2),用于前台办公普通用户帐户。

当我创建管理员的条目(例如,ID为1)的帐户,我得到在表中的customer_id,DEPARTMENT_ID,USER_ID为(1,1,1)文我试图创建一个后台管理部门的ID是一款入门2。

当我检查了管理员用户的能力列表;我发现有条目能力即重复,

#<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
答案

我用有点不同的方法对这样的:

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

当然这只是一个模板

以上是关于Rails的基于部门CanCanCan资源的能力的主要内容,如果未能解决你的问题,请参考以下文章

Rails - CanCanCan - 常用能力

Rails 设计角色模型和 CanCanCan - 定义能力

Rails、Devise、Role Model 和 CanCanCan - 定义能力

rails+devise+cancancan+rolify注册登录多角色权限管理

Cancancan 通过能力检查传递一个对象

ruby 为cancancan编写能力文件的示例