开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜