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

あなたが簡単に使用することができますscope syntax 4レールのように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

あなたscope方法は、あなたのモジュールはルビーによって解析されたときにすぐに呼び出されると、それはあなたのCommonScopesモジュールからアクセス可能ではありませんされているので...

しかし、あなたはクラスメソッドで、あなたのスコープの呼び出しを置き換えることができます。

module CommonScopes 
    extend ActiveSupport::Concern 

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

を使用することができますラムダはコードの実行を遅らせます(レール3でも使えます):

module CommonScopes 
    extend ActiveSupport::Concern 

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

のように、Rails 3と4の両方のためです。これは良い方法です。 –

関連する問題