2011-12-06 6 views
12
中関係に基づいてチェーン可能スコープを設定するのです

問題を修正しました...どのようにMongoid

予想通りになりましたすべての作品、書か乗り越えアクティブレコード方法があったが、私はセットアップしようとしていますスコープので、私は マイモデルをイベントに出席したタイプのすべての競技者が

class Competitor < Competitor 
    belongs_to :type 
    has_and_belongs_to_many :events 
    scope :at_event, ->(event) {where(:event_ids.in => event.competitor_ids)} 
    scope :of_type, ->(type) where(:type_id => type.id)     
end 
ようになります戻ります

Competitor.of_type(type).at_event(event) 

のように見える電話をかけることができます

次作品(mongoid基準を返す)

Competitor.of_type(type) 
Competitor.at_event(event) 

しかし、私はそれらをチェーンするとき、それはこのようなものプリントアウトし:競合他社のそれぞれについて、競争相手のエントリがあります

#<Competitor:0x00000109e2b210> 
#<Competitor:0x00000109e2ab08> 
-------=-=------------------------------------ 
=> #<Mongoid::Criteria 
selector: {}, 
options: {}, 
class: Competitor, 
embedded: false> 

を。 of_type(type)(最初の連鎖した基準)、クエリで.countを実行すると、データベース内の競合者の総数が取得されます。

スコープのマニュアルのトップには、すべてのスコープが連鎖可能であり、関連付けにも適用できることが記載されています。これについては後の節で説明します。 残念ながら私はリレーションサブセクションを見ませんでしたが、メインリレーションセクションのスコープに対する単一の参照を見つけることはできませんでした。

は私が望んでいた結果を返すために、以下を得ることができた:
where(:id.in => event.competitor_ids).where(:type_id => type.id) 

が、クエリのいずれかの部分が別々の方法や範囲に分割されている場合、それは失敗し、私は上記の示した結果を提供してい

。 Active Recordのと同様に

+0

ご自身で質問し、解決済みとマークしてください。 –

答えて

8

スコープ

、Mongoidは、フィルタリング結果セットの利便性としてあなた モデルのスコープを定義することができます。スコープは、スコープマクロを使用するか、または基準オブジェクトを返すクラス メソッドを定義することによって、クラスレベルで と定義されます。すべてのスコープは連鎖可能であり、 も関連に適用できます。後で説明するのは の関連セクションです。

名前付きスコープは、スコープマクロを使用してクラスレベルで定義され、素晴らしいDSLで結果セットを作成するために連鎖させることができます。

class Person 
    include Mongoid::Document 
    field :occupation, type: String 
    field :age, type: Integer 

    scope :rock_n_rolla, where(occupation: "Rockstar") 
    scope :washed_up, where(:age.gt => 30) 
    scope :over, ->(limit) { where(:age.gt => limit) } 
end 

# Find all the rockstars. 
Person.rock_n_rolla 

# Find all rockstars that should probably quit. 
Person.washed_up.rock_n_rolla 

# Find a criteria with Keith Richards in it. 
Person.rock_n_rolla.over(60) 

定義は、クラスのロード時に評価されている注意してください。実行時に を評価する場合は、 procまたはlambdaを使用して定義する必要があります。次の例では、最初の日付がクラスロードの日付 に設定されています.2番目のスコープは、スコープが呼び出された時刻 の日付を設定します。データマッパー形式の構文を好む人のために

scope :current, where(:start_date.lte => Date.today) 
scope :current, -> { where(:start_date.lte => Date.today) } 

クラスメソッド

、基準を返すクラスメソッドは、同様にチェーン可能なスコープとして扱うことができます。基準を返す

class Person 
    include Mongoid::Document 
    field :occupation, type: String 
    field :age, type: Integer 

    class << self 

    def rock_n_rolla 
     where(occupation: "Rockstar") 
    end 

    def washed_up 
     where(:age.gt => 30) 
    end 

    def over(limit) 
     where(:age.gt => limit) 
    end 
    end 
end 

# Find all the rockstars. 
Person.rock_n_rolla 

# Find all rockstars that should probably quit. 
Person.washed_up.rock_n_rolla 

# Find a criteria with Keith Richards in it. 
Person.rock_n_rolla.over(60) 

名前付きスコープとクラスメソッドが互いに連鎖することができます - それはMongoidの強力な基準のAPIの美しさです。

class Person 
    include Mongoid::Document 
    field :occupation, type: String 
    field :age, type: Integer 

    scope :washed_up, where(:age.gt => 30) 
    scope :over, ->(limit) { where(:age.gt => limit) } 

    def self.rock_n_rolla 
    where(occupation: "Rockstar") 
    end 
end 

# Same queries apply here as well. 
Person.rock_n_rolla 
Person.washed_up.rock_n_rolla 
Person.rock_n_rolla.over(60) 
+0

これを使用して、現在のモデルとの関係ですべてのモデルを見つけるにはどうすればよいですか?例えば、「Person.rock_n_rolla.bands」とすると、職業RockstarのPersonに属するすべてのバンドを取得できますか? –

関連する問題