2016-01-06 41 views
0

我在使用Cancancan進行角色授權的Rails 4中構建應用程序。我有一個能力定義,適用於單個記錄,但不適用:索引操作。Rails/Cancancan:通過複雜/作用域查詢來定義能力

我有一個名爲'RVSP'的用戶角色。 RVSP分配爲WorkOrders,RVSP將從中創建Record

class WorkOrder < ActiveRecord::Base 
    has_one :record 
    belongs_to :rvsp, class_name: "User" 
end 

class Record < ActiveRecord::Base 
    belongs_to :work_order 
end 

這裏是我的問題:我想RVSP用戶能夠讀取或更新Records其中WorkOrder被分配到該RVSP。這裏的能力定義至今:

can [:read, :update], Record, Record.for_rvsp(user.id) do |record| 
    work_order = record.work_order 
    user.id == work_order.rvsp_id 
end 

範圍Record.for_rvsp在這個畸形:

scope :for_rvsp, -> (rvsp_id) { where(work_order: { rvsp: { id: rvsp_id } }) } 

所以:我如何定義所有Records的能力和/或查詢的Record'sWorkOrder'srvsp_id匹配當前用戶的ID?我懷疑這是一種加入,但我是新來的,並沒有這樣做過。

P.S.我想只是增加一個created_by列到Record,但我已經通過PaperTrail,我正在使用審計跟蹤。但就查詢的難度而言,Record.versions.first.whodunnitRecord.work_order.rvsp_id大致相同。感謝您提供的任何建議!

P.P.S.我使用Postgres,但我寧願不做任何數據庫特定的SQL,如果我能避免它。

+0

爲什麼這不起作用? :'can [:read,:update],Record,work_order:{rvsp:{id:user.id}}' –

回答

2

我開始敲打連接,它似乎在工作!我換成上面下面的類方法的適用範圍:

def self.for_rvsp(rvsp_id) 
    joins(:work_order).where(work_orders: {rvsp_id: rvsp_id}) 
end 

我也收拾了能力Ability.rb:

can [:read, :update], Record, Record.for_rvsp(user.id) do |record| 
    user.id == record.work_order.rvsp_id 
end 

所以,就指數的行爲而言,看來你需要在兩個地方做同樣的事情:你定義一個範圍來獲取你需要的記錄,然後你在塊中定義這個能力。範圍確保您加載所有正確的記錄,並且能力塊授權他們。無論如何,似乎爲我工作!