Ruby CanCanCan 动态定义方法

灵感来自这里https://github.com/kristianmandrup/cantango/wiki/CanCan-vs-CanTango

如果权限不多,我们可以通过这种方式来定义

ruby 复制代码
class CanCan::Ability
  def initialize user, options = {}
    if !user
      can :read, :all
    end
    if user
      admin_rules if user.roles.include? :admin
      editor_rules if user.roles.include? :editor
      default_rules
    end
  end

  def admin_rules
    can :manage, :all
  end

  def editor_rules
    can :manage, [Article, Post]
  end
end

改的灵活点

ruby 复制代码
class CanCan::Ability
  def initialize user, options = {}
    user ? user_rules : guest_user_rules
  end

  def user_rules
    user.roles.each do |role|
      exec_role_rules(role) if user.roles.include? role
    end
    default_rules
  end

  def exec_role_rules role
    meth = :"#{role}_rules"
    send(meth) if respond_to? meth
  end
  
  # various rules methods for each role
  def admin_rules
    can :manage, :all
  end

  def editor_rules
    can :manage, [Article, Post]
  end
  ...

  def default_rules
    can :read, :all
  end
end

上面是原文出处,实际使用的时候还是不方便,我改成这样了(非一比一还原)。使用define_method 定义那个每个方法:

ruby 复制代码
class Ability
  include CanCan::Ability

  @@permissions = xxx
  def initialize(user)
    @user= user|| User.new
    @user.roles.each do |role|
       exec_role_rules(role) if @user.has_role?(role)
    end
  end

  Role.all.each do |role|
    define_method "rules_#{role.name.gsub(" ", "_")}" do
      role_permissions = RolePermission.where(role_id: role.id)
      unless role_permissions.blank?
        role_permissions.each do |rp|
          permission_value = @@permissions[rp.permission_key]
          entities = permission_value["entities"].map{|e| e.constantize}
          actions = permission_value["actions"].map{|e| e.to_sym}
          can actions, entities
        end
      end
    end
  end

  def exec_role_rules(role)
    meth = :"rules_#{role.name.gsub(" ", "_")}"
    send(meth) if respond_to? meth
  end

end

经测试嘎嘎好用,就是我还需要添加一些条件筛选,导致我这个不能用,得删掉,有点可惜,记录一下~

相关推荐
kimnoic5 小时前
Python数据库学习心得:SQLite、MySQL、PostgreSQL优缺点
开发语言·python
必须得开心呀6 小时前
python编写带界面的软件,需要安装哪些插件
开发语言·python
沫璃染墨8 小时前
《Qt从零入门系列(十三):QSS样式表详解——从选择器与层叠规则到控件美化实战》
开发语言·css·c++·qt·ui·qt6.3·qss
达子6669 小时前
RUST 图解 第 3 章:通用编程概念(Common Programming Concepts)
开发语言·算法·rust
道尔柯南9 小时前
C++ 面向对象编程入门:类和对象(上)
开发语言·c++·算法
楠楠子呀9 小时前
英语、西语、阿语客户各开一个口:多语言获客的分流方案
开发语言·javascript·ecmascript·跨境电商·whatsapp·营销工具
tachibana210 小时前
使用for range 的时候,它的地址会发生变化吗?
开发语言·后端·golang·go·语法
临床数据科学和人工智能兴趣组10 小时前
正则表达式的基础语法的基本符号
开发语言·人工智能·python·正则表达式·r语言·r语言-4.2.1·workbudyy
王中阳Go10 小时前
Go 后端转 AI:非科班怎么补?一张 3 列路线表(可保存)
开发语言·人工智能·后端·python·golang·大语言模型
geats人山人海11 小时前
java 4继承
java·开发语言