2012-10-11 195 views
2

我有一個項目模型和一個開發人員模型。我有計算某個項目的「興趣」爲一個特定的開發商的概念:覆蓋AR訂單範圍

class Project < ActiveRecord::Base 
    def interestingness_for(developer) 
    some_integer_based_on_some_calculations 
    end 
end 

我認爲這將是整齊的,而不必像Project.order_by_interestingness_for(bill),要能說

Project.order(:interestingness, :developer => bill) 

,並讓它成爲一個範圍,而不是隻是一個函數,所以我可以做的東西一樣

Project.order(:interestingness, :developer => bill).limit(10) 

我不知道如何做到這一點,雖然,因爲這不是明顯對我如何覆蓋範圍。有什麼建議?

回答

0

假設你將不再需要使用標準的ActiveRecord order查詢方法爲項目類,你可以重寫它像任何其他類方法:

def self.order(type, options) 
    self.send(:"special_#{type}_calculation_via_scopes", options) 
end 

然後,關鍵是要確保你創建所需的計算方法(根據您的興趣和其他算法而定)。而計算方法只使用範圍或其他AR查詢接口方法。如果您不習慣使用查詢界面將方法邏輯轉換爲SQL等效項,則可以嘗試使用可能直接根據具體計算使用該方法的Squeel DSL gem。

如果您可能需要傳統的order方法(並且這通常是一個安全的假設),那麼請不要覆蓋它。要麼爲此創建代理非ActiveRecord對象,要麼使用不同的命名約定。

如果你真的想要,你可以使用別名來達到類似的效果,但是如果第二個參數(在這種情況下爲'options')在Rails進程中突然出現另一個含義,它可能會對長期產生意想不到的後果。這裏是您可以使用的一個例子:

def self.order_with_options(type, options = nil) 
    if options.nil? 
    order_without_options(type) 
    else 
    self.send(:"special_#{type}_calculation_via_scopes", options) 
    end 
end  
class << self 
    alias_method_chain :order, :options 
end 
+0

你是說這是不可能覆蓋'order',使其返回如果'options'傳遞我的客戶訂單的結果,但如果返回'選擇本地訂購操作結果'是空的? –

+0

完全不可能,使用別名肯定是可行的。由於公約的變化,不推薦參加嚴肅的項目。更新以演示這一點。 – PinnyM