2009-04-24 51 views
1

縱觀我們的網站有一個共同的模型,讓基於控制器,動作,請求參數的說視頻,有一些像私人/公共/未決,可下載的屬性等語境的ActiveRecord模型濾波

和目前的用戶,我們想要過濾出顯示的特定視頻。例如,在主頁上我們只想顯示公開的視頻。如果主頁上有登錄的用戶,我們也想顯示公開下載的視頻。

我們也希望確保這些過濾器可以通過單獨的SQL查詢被應用,因此使用獅身人面像,當用戶確實在網站上搜索,我們可以過濾掉不想要的視頻。

難道這最好是通過授權插件處理,比如導軌授權 - 插件?底線我們的目標是阻止程序員無意中忘記,當他們添加一個新的動作來過濾掉特定的視頻。我們正在尋找的解決方案應該是非常程序化的。

這裏是我想的解決方案(沒有編寫任何代碼還)

  1. 製作使用authroization插件或推出我們自己的,允許其顯示的視頻設置,在控制器中定義或行動水平。

  2. 爲has_many(:videos)或has_one(:video)的任何模型創建關聯擴展,這允許我們重載關聯中視頻的查找器。

  3. 重載Video.find以類似的方式來限制顯示基於當前的規則的內容。

回答

3

您的一般策略聽起來很合理,但我強烈建議您不要重寫rails default finders。取而代之的是,這裏的東西我在過去所做的:

class Video < ActiveRecord::Base 
    named_scope :available_to, lambda {|user| 
    if user.nil? 
     :conditions => {:public_accessible => true} 
    elsif user.omnipotent? 
     {} 
    else 
     :conditions => [%{ 
     videos.public_accessible = ? OR EXISTS (
      ....boring security stuff linking to users.... 
     ) 
     }, true, user.id] 
    end 
    } 
end 

然後在video_shop.rb:

class VideoShop < ActiveRecord::Base 
    has_many :videos 
end 

最後,把它放在一起:

# All videos available to a user 
Video.available_to(user) 

# All videos in a given shop 
video_shop.videos 

# All videos in a given shop available to a given user 
video_shop.videos.available_to(user) 

注意這些工作即使用戶是零。

+0

這很酷。 – 2009-04-30 14:28:34