2011-09-06 2 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

람다를 지금 선호해야한다고 생각하지 않습니까? – mdemolin

+0

@mdemolin 나는 람다없이'scope'를 호출하는 것이 레일 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 당신이 간단하게 사용할 수있는 코드 실행을 지연시키는 람다 (레일 3에서도 작동) :

module CommonScopes 
    extend ActiveSupport::Concern 

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

에서와 같이 레일 3과 4 모두를위한 것입니다. 더 나은 방법입니다. –

관련 문제