Cancan能力定义:整个控制器作为对象

时间:2012-05-14 21:21:39

标签: ruby-on-rails controller cancan

我的问题绝对理论化,比如“这是正确的事吗?”。 我是Rails的新手,特别是Ruby的新手,我正在尝试将Cancan自动化解决方案用于我的Rails appilcation。

让我们考虑一下这样的简单控制器,一对关联视图和一个带DB表的User模型。

class UsersController < ApplicationController
  def index
    @users = User.all
  end
  def show
    @user = User.find(params[:id])
  end
end

目标是将“索引”方法的访问限制为除管理员之外的所有人,并允许普通用户仅查看他们自己的页面,例如允许id == 5的用户查看页面“users / 5”。 对于这个范围,我为Cancan创建了一个能力类。这是:

class Ability
  include CanCan::Ability

  def initialize user, options = {}
    default_rules
    if user
      admin_rules(user) if user.role.eql? "admin"
      player_rules(user) if user.role.eql? "player"
    end
  end

  def admin_rules user
    can :read, UsersController
  end

  def player_rules user
    can :read, User do |user_requested|
      user_requested.id == user.id
    end 
  end

  def default_rules 
  end
end

我的问题是: 如果我没有类型User的方便用户,我应该在“can”方法中使用UsersController作为对象吗?稍后通过控制器的“索引”方法中的“authorize!:show,UsersController”来应用它。或者它应该以其他方式完成? 谢谢你的建议。

4 个答案:

答案 0 :(得分:2)

不,您不想将UsersController添加到CanCan。

CanCan旨在授权资源,而不是Rails控制器。

我建议如下:

def initialize(user)
  if user.is_admin?
    can :manage, User
  else
    can :manage, User, :id => user.id
  end
end

这将允许用户仅访问他自己的用户,除非他是管理员。 请参阅CanCan Wiki中的Defining abilities页面

答案 1 :(得分:0)

我使用符号,例如,在Ability类

def initialize(user)
  if user.is_admin?
    can :any, :admin
  end
end

并在控制器中

authorize! :any, :admin

答案 2 :(得分:0)

+1到@Tigraine。

按照他的指示......

class Ability
  include CanCan::Ability

  def initialize user, options = {}
    default_rules
    if user
      admin_rules(user) if user.role.eql? "admin"
      player_rules(user) if user.role.eql? "player"
    end
  end

  def admin_rules user
    can :manage, User
  end

  def player_rules user
    can :manage, User :id => user.id
  end

  def default_rules 
  end
end

并在您的控制器中执行此操作...

class UsersController < ApplicationController
  load_and_authorize_resource
  # => @users for index
  # => @user for show

  def index
  end
  def show
  end
end

有关load_and_authorize_resource的详细信息,请参阅this link

的底部

答案 3 :(得分:0)

在维基中,我找到了另一种设置能力的方法。虽然它有点先进,check it out here

   ApplicationController.subclasses.each do |controller|
        if controller.respond_to?(:permission)  
          clazz, description = controller.permission
          write_permission(clazz, "manage", description, "All operations")
          controller.action_methods.each do |action|
...