cancanfunction在单独的文件中

是否可以在单独的文件中定义能力并将它们包含在initialize方法中的ability.rb文件中?

下面的代码返回:尝试并得到:未定义的方法’可以’

ability.rb

def initialize(user) include MyExtension::Something::CustomAbilities ... end 

LIB / my_extension / something.rb

 module MyExtension::Something module CustomAbilities can :do_it, Project do |project| check_something_here and return true or false... end end end 

如果可能的话,完美的解决方案是使用Ability.send扩展类能力:include / extend,所以没有在initialize方法中明确包含

只需包含模块并在initialize调用方法

这里的技巧是为你的每个能力创建模块,将它们包含在你的基本ability.rb文件中,然后在你的initialize方法中运行特定的方法,如下所示:

在你的ability.rb文件中:

 class Ability include CanCan::Ability include ProjectAbilities def initialize user # Your "base" abilities are defined here. project_abilities user end end 

lib/project_abilities.rb文件中:

 module ProjectAbilities def project_abilities user # New abilities go here and later get added to the initialize method # of the base Ability class. can :read, Project do |project| user.can? :read, project.client || user.is_an_admin? end end end 

使用此模式,您可以将您的能力分解为各种模块(可能,每个模型都有一个模块,您必须为其定义用户能力)。

看看Pundit

另外值得注意的是,看一下名为Pundit的(相对)新gem,它为大型网站的授权提供了更加可扩展的模式。

干杯,

J.P

使用更现代的ruby,您可以通过prepend实现这一目标

 module CashBalance attr_accessor :balance def deposit(amount) self.balance += amount end def withdraw(amount) self.balance -= amount end def initialize(*args) self.balance = 0.0 super end end class Bank prepend CashBalance def initialize(name) @name = name end def dump puts "%s has a balance of %0.2f" % [ @name, balance ] end end b = Bank.new("Fleet") b.deposit(20) b.dump b.withdraw(10) b.dump 

产量

 $ ruby blarg.rb Fleet has a balance of 20.00 Fleet has a balance of 10.00