我想要一些应该都具有范围(同名)的子类。虽然我知道直接继承是不可能的,但基本思路如下:
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
总的来说,我想要一组所有已经通过设计实现此范围的类,而不仅仅是因为开发人员决定这样做。
有什么想法吗?
答案 0 :(得分:3)
您可以使用mixin而不是超类来执行此操作:
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
这会将范围注入每个实例。
答案 1 :(得分:2)
我今天遇到了同样的问题,并找到了上面提供的mixin解决方案的替代方案。感谢Arel, .where , .order 等所有返回范围。所以你实际上可以用类方法替换你的范围:
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
在几乎所有情况下,我发现这种方法比mixin解决方案更清洁,更容易。