在RoR中向CanCan传递参数

9

我有一个控制器,其中有一个类似于以下的方法:

def show

    if params[:format].eql?("pdf")
    // do something
    elsif params[:format].eql?("csv")
    // do something
    end
end

但我有不同角色的用户。因此,我使用CanCan来管理访问控制。 现在我希望X角色可以在控制器中执行show操作,仅当params[:format].eql?("csv")时。

我认为它可以像这样:can :show, resource if params[:format].eql?("csv")。那么,我如何将参数发送到ability.rb中呢?

有任何想法吗?

谢谢。

3个回答

30

在ApplicationController中添加以下内容:

# CanCan - pass params in to Ability
# https://github.com/ryanb/cancan/issues/133
def current_ability
  @current_ability ||= Ability.new(current_user, params)
end

3
完美 - 只是缩进了4个空格:D - Hendrik

8

1

can 接受两个参数:第一个是用户试图在资源上执行的操作类型,第二个是资源本身(可以是类名或实例变量)。如果您正确设置了您的 Ability,您应该能够像这样做:

def show
  if params[:format].eql?("pdf")
    // do something
  elsif params[:format].eql?("csv")
    if can? :read, resource
      #do stuff
    end
  end
end

不要忘记在运行任何CanCan检查之前对用户进行身份验证。 can?方法只返回true或false。我通常喜欢使用authorize!方法来检查权限。与can不同,它会引发CanCan :: AccessDenied错误,您可以优雅地进行救援和处理。类似于以下内容:
#models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)

    if user.role? :admin
      can :manage, :all
    elsif user.role? :hiring_manager
      can [:read, :update], Post, user_id: user.id
    end
  end
 end

#controllers/posts_controller.rb
class PostsController < ApplicationController::Base
  before_filter :authenticate_user

  def show
    @post = Post.find(params[:id])
    authorize! :read, @post # will thorow an exception if not allowed
  end
end 

然后,我只是在ApplicationController级别捕获异常。


很好的例子,Simon,但这不是我想要的。因为我只是用 params[:format] 来决定方法的行为。在你的例子中,你使用 params 来查找记录。该记录传递给 ability 以决定访问控制。但我没有按照你的方式使用 params。 - Çağdaş

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接