2011-09-06 67 views
16

我想通过移动共享范围到一个模块中干涸的几款机型,这样的:通过模块共享示波器?

module CommonScopes 
    extend ActiveSupport::Concern 

    module ClassMethods 
    scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc") 
    end 
end 

我也希望创建一个测试模块共享功能。不幸的是,当我尝试在我的模型中包含共享示波器时,我得到:

undefined method `order' for CommonScopes::ClassMethods:Module 

任何想法?谢谢!

回答

13

可以在轨使用instance_eval

module CommonScopes 
    extend ActiveSupport::Concern 

    def self.included(klass) 
    klass.instance_eval do 
     scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc") 
    end 
    end 
end 
+0

难道你不认为lambda应该是首选吗? – mdemolin

+0

@mdemolin我相信在没有lambda的情况下调用'scope'在rails 4中已被弃用了。 – Gazler

+1

正是我所说的:)(但我认为它只是现在的首选语法,而不是弃用) – mdemolin

2

因为当你的模块是由红宝石解析,它不是从你的CommonScopes模块可访问您的scope方法是直接调用..

,但可以更换的一类方法的范围内调用:

module CommonScopes 
    extend ActiveSupport::Concern 

    module ClassMethods 
    def ordered_for_display 
     order("#{self.to_s.tableize}.rank asc") 
    end 
    end 
end 
37

由于4 scope syntax,你可以简单地使用lambda延迟代码的执行(在rails 3中也有效):

module CommonScopes 
    extend ActiveSupport::Concern 

    included do 
    scope :ordered_for_display, -> { order("#{self.to_s.tableize}.rank asc") } 
    end 
end 
+0

这是更好的方法。 –