2012-02-27 29 views
8

我有一個類似於如下方法的控制器:在RoR中傳遞參數給CanCan

def show 

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

但我有不同角色的用戶。所以我使用CanCan來管理訪問控制。 現在我想X角色可以在控制器中執行操作show iff params[:format].eql?("csv")

我認爲它可以像; can :show, resource if params[:format].eql?("csv")。那麼我如何發送參數到ability.rb?

有什麼想法?

謝謝。

回答

24

在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 
+0

這應該被標記爲答案。謝謝! – 2013-05-15 17:20:17

+1

完美 - 除了縮進4個空格:D – Hendrik 2017-01-19 13:50:01

1

can使用兩個參數:第一個是用戶正試圖對資源執行的動作的類型,第二個是資源(可以是類名或實例變量)本身。如果你有你的能力設置正確,你應該能夠做這樣的事情:

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

不要忘記,你必須有你的用戶運行任何慘慘檢查之前進行身份驗證。 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級別捕獲異常。

+0

很好的例子西蒙,但它不是我所期待的。因爲我只是使用params [:format]來決定方法的行爲。在你的例子中,你使用params來查找記錄。記錄傳遞給決定訪問控制的能力。但我沒有用你的方式使用params。 – 2012-02-27 22:23:46