2013-03-29 30 views
3

我試圖將cancan納入我的第一個Ruby on Rails應用程序。cancan並未評估實例級別的能力檢查

我有一個問題,開始......它肯定是一些基本的東西。

我的應用程序有一個項目列表,並且用戶可能有也可能沒有權限查看任何數量的項目。

我將此添加到我的ProjectsController:

class ProjectsController < ApplicationController 
    load_and_authorize_resource 

我的初始化方法是這樣的:

def initialize(user) 
    user ||= User.new # guest user 
    puts "******** Evaluating cancan permissions for: " + user.inspect 
    can :read, Project do |project| 
     puts "******** Evaluating project permissions for: " + project.inspect 
     # project.try(project_users).any?{|project_user| project_user.user == user} 
     1 == 1 #POC test! 
    end 
    end 

當我有這個,出現項目索引頁,但沒有項目被列出。

2個問題我這裏有:

  1. 應該不是所有的項目出現,因爲返回true所有 項目?
  2. 第二個puts語句不寫入導軌 服務器控制檯,但第一個是。這是爲什麼???

如果我改變初始化方法:

def initialize(user) 
    user ||= User.new # guest user 
    puts "******** Evaluating cancan permissions for: " + user.inspect 
    can :read, Project 
    end 

...我看到所有的項目作爲我希望

如果我刪除即可:讀,項目行,我得到一個安全異常,試圖擊中項目索引頁....也是我所期望的。

回答

0

傳遞給:read能力的塊僅在項目實例可用時才被評估(@project)。由於您正在討論索引操作,因此只有收集可用(@projects)。這就解釋了爲什麼你的第二個陳述不會出現。爲了限制您的索引操作,您需要將條件散列值傳遞給can方法,或使用範圍(除了塊)。所有這些信息都在Github的CanCan wiki中清楚地概述。

所以puts問題是可以解釋的。沒有意義的是沒有項目展示。在評估索引動作時,CanCan實際上會默認完全忽略該塊。這意味着你的能力無論如何(甚至在第一個例子中)都是指數行動的基本要素。

我會有興趣試着添加一個簡單的範圍,看看它是否會工作。請嘗試:

can :read, Project, Project.scoped do |project| 
    true 
end 

然後查看索引操作會發生什麼。

編輯:

既然你可以看到項目在索引現在,好像你需要傳遞到範圍的能力,以及作爲一個塊。請閱讀this Github issue,Ryan解釋了爲什麼該塊未在索引操作上進行評估。

塊僅用於基於對象的屬性定義功能。 [...]這是唯一的情況,當一個塊應該使用 時,因爲該塊僅在對象爲 可用時才執行。所有其他條件應在塊外定義。

請記住,如果你的能力不是太複雜的條件散列,你應該使用它。條件散列在this CanCan wiki page on Github.上進行了解釋如果您確實需要一個範圍,則需要傳入範圍和塊。可以說你有上面顯示的能力。

  1. 在索引操作上,CanCan將忽略該塊,因爲Project對象(@project)不可用。它將返回給定範圍內的項目,在這種情況下爲Project.scoped(這將只是所有項目)。
  2. 在展示動作中,@project可用,因此CanCan將評估該塊並在塊評估爲true時允許該操作。

因此,您需要傳遞兩者的原因是CanCan可以同時處理索引和顯示操作。在大多數情況下,您的塊將定義與範圍相同的內容,只有塊將用Ruby編寫,而範圍將寫入Rails的ActiveRecord語法。你可以在這裏獲得更多的信息:Defining Abilities with Blocks

+0

我得到:未定義的方法'範圍'爲#<數組:0x43cbc30>。我會繼續研究爲什麼我會得到這個,但不希望我的紅寶石新手打斷你的慷慨行爲。 – Doug

+0

錯誤,請嘗試'Project.scoped'。 'all' pre-Rails 4將返回一組記錄,而不是'ActiveRecord :: Relation'。 –

+0

這是相當謙卑:未定義的方法'包括?'對於# Doug