2011-03-23 31 views
3

我希望有幾個子類都應該有一個範圍(具有相同的名稱)。雖然我知道這是不可能的直繼承的基本思路是:如何通過抽象活動記錄將範圍添加到子類中

class MySuperClass << ActiveRecord::Base 
abstract_class = true 
scope :scopeForAllSubclasses , lambda {|my_var| where(:var => my_var)} 
end 

class Subclass1 << MySuperClass 
#has attribute var 
end 

class Subclass2 << MySuperClass 
# has attribute var 
end 

所以現在我想打電話給

Subclass1.scopeForAllSubclasses123).all 

Subclass2.scopeForAllSubclasses(123).all 

整點它是我想要一組所有已經通過設計實現了這個範圍的類,而不僅僅是因爲開發者決定這樣做。

任何想法?

回答

3

你可以用一個混合的,而不是一個超做到這一點:

module ScopeBuddy 
    def self.included base 
    base.instance_eval "scope :scopeForAllSubclasses , lambda {|my_var| where(:var => my_var)}" 
    end 
end 

class ClassA 
    include ScopeBuddy 
end 

class ClassB 
    include ScopeBuddy 
end 

這將注入範圍爲每個實例。

+0

這是一個不錯的解決方案。然而:在超類上定義的子類和範圍在Rails 2.X中工作,所以Rails 3在這方面退步...... :( – severin 2012-06-05 10:05:16

2

今天我遇到了同樣的問題,發現上面提供的mixin解決方案的替代方案。感謝Arel,,其中,。訂購等全部返回範圍。所以,你實際上可以只是類方法取代你的範圍:

class MySuperClass << ActiveRecord::Base 
    abstract_class = true 

    def self.scopeForAllSubclasses(my_var) 
    where(:var => my_var) 
    end 
end 

MySuperClass.scopeForAllSubclasses('something') # => returns results from all subclasses 
Subclass1.scopeForAllSubclasses('something') # => returns results from just Subclass1 
Subclass2.scopeForAllSubclasses('something') # => returns results from just Subclass2 

我發現這種方法清潔和更容易比幾乎在每一個狀況混入的解決方案。

+0

這有限制,您不能應用範圍修剪下來一旦他們已經被檢索到記錄數組,但對於基本查詢,效果很好! – 2012-11-20 18:21:58

+1

我很抱歉,但我不明白你的意思是「一旦記錄已被檢索,修剪記錄數組」。你不能將範圍應用到獲取對象的數組中......並且*方法範圍*正如我的答案中所解釋的return /僅僅是範圍,所以你可以像範圍那樣鏈接它們...... – severin 2012-11-21 08:56:15

相關問題