how can I add a scope to subclass class through abstract active record
I would like to have a few subclasses that should all have a scope (of the same name). Although I know this is not possible with straight inheritance the basic idea is the following:
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
So now I want to call
Subclass1.scopeForAllSubclasses123).all
and
Subclass2.scopeForAllSubclasses(123).all
The whole开发者_开发问答 point it that I want a group of classes that all have implemented this scope by design rather than just because the developer decided to do so.
Any ideas?
You could do this with a mixin instead of a superclass:
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
This will inject the scope into each instance.
I ran into the same problem today and found an alternative to the mixin solution provided above. Thanks to Arel, .where, .order etc. all return scopes. So you can actually just replace your scopes with class methods:
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
I find this approach cleaner and easier than the mixin solution in almost every situation.
精彩评论