CanCan,在Ability#initialize中将块传递给can方法有什么用呢?

时间:2013-08-25 06:47:32

标签: ruby-on-rails ruby authentication authorization cancan

这是我的Ability.rb文件:

class Ability
  include CanCan::Ability

  def initialize(user)
    user.permissions.each do |permission|
      can permission.action.to_sym,
          permission.thing_type.constantize {|thing| thing.nil? || permission.thing.nil? || permission.thing_id == thing.id}
    end
  end
end

事情是多态关联。我试图了解如何通过一个块可以工作。我已经在整个wiki中搜索了CanCan但是还没有找到解释。

1 个答案:

答案 0 :(得分:1)

将块传递给cancan允许您实现更复杂的权限检查,这些检查取决于对象本身的状态。

当它只是你要检查的对象的属性时,你不需要一个块:

can :read, Project, :active => true

允许用户只读取活动项目。如果您需要调用项目的editable方法,那么您可以改为

can :read, Project do |project|
  project.editable?
end

在cancan检查你是否可以读取特定项目时(即当before_filter触发或你调用`可以?:read,some_project)然后调用该块

在wiki上有一个关于此的页面:Defining abilities with blocks

在您的情况下,看起来意图是权限对象可以授予对整个类的访问权限(如果thing_type已设置但thing_id为空)或者该类的特定实例。

但是,您发布的代码实际上并没有这样做。在传递块的两种方式中,{}do...end绑定得更紧密,因此块根本不会传递给can。它被传递给constantize,忽略它。您可以使用括号或使用do...end

来消除歧义