2011-07-26 9 views
2

私たちはレール2アプリをアップデートしています。私たちは幸いに、fake_arelを使用しています。これは非常に素晴らしい "または"スコープを提供します。rails 3 - 'or' scope

今、レール3で私はこれを複製する方法を見つけることができません。

私たちは、このようなコードを持っている:

scope.or(Event.horse, Event.dog, Event.trap).today 

モデルは次のようになります。

class Event < ActiveRecord::Base 
named_scope :horse, lambda { {:conditions => ["sport_category_id in (?)", SportCategory.find_horse_ids] }} 
named_scope :dog, lambda { {:conditions => ["sport_category_id in (?)", SportCategory.find_dog_ids] }} 
named_scope :trap, lambda { {:conditions => ["sport_category_id in (?)", SportCategory.find_trap_ids] }} 
end 

これらのスコープは、別である必要があり、すべての場所で使用されています。このモデルには、実際に組み合わせて使用​​される数十のスコープがあります。したがって、すべてを書き直すことが、私たちがやりたい最後のものです。

「または」スコープを一緒に使用できないことは奇妙に思えます。

誰かがRails 3でうまくいく方法を提案できますか?アイルを使用しても、私はどのように表示されません。 私たちは別のプロジェクトでmeta_whereを使用していますが、そのようなことはありません。

答えて

1

まあ、それを行う方法があり、あなたのモデルに(あなたのニーズに適合させる!):

where(:event => ['horse', 'dog', 'trap']) 

配列は、あなたがそこに欲しいものである文を生成します。さらに、あなたはそれを達成するためにレール3つのスコープを使用することができます。

scope :my_scope, where(:event => ['horse', 'dog', 'trap']) 

その後、あなたはこのようにそれを使用することができます。

mymodel.my_scope # and possibility to chain, like : 
mymodel.my_scope.where(:public => true) 
+0

多分、私はこれをどこに置くべきか理解していません。もし私がそれを私のイベントモデルに入れたら(スコープ:find_scope、どこで(:event => ['馬'、 '犬'、 'トラップ')))私は得る:ActiveRecord :: StatementInvalid: ''イベント 'のために存在します – phil

+0

それは私が書いた理由です:あなたのニーズにそれを適応させてください!あなたのモデルをここに投稿すると、私はそれを理解するのを手伝います。 –

+0

モデルを更新しました。私はあなたがしていることがどうもどのように既存のスコープを呼び出すのかを見ることはできません。それは全体の問題です。 – phil

0

私はfake_arelから「または」機能をリッピングし、それがレールでの作業ました3.0xの(私たちはそのここで使用していないとして、それは3.1で動作するかどうかわからない)

私は誰もが私はgistでそれを入れている興味を持っているケース:

0

私は取得できませんでしたPhilがGithub-gistのコードを書いていましたが、それが私にはもっと簡単な解決策だと思う次のものを思いついたのです。それにもかかわらず、ActiveRecord :: Relationクラスを返すクラスメソッドを使用します。

def self.or alt_scope 
    either = scoped.where_clauses.join(' AND ') 
    alternative = alt_scope.where_clauses.join(' AND ') 

    Locatie.unscoped.where("(#{either}) OR (#{alternative})"). 
    joins(scoped.joins_values).joins(alt_scope.joins_values). 
    group(scoped.group_values).group(alt_scope.group_values). 
    having(scoped.having_values).having(alt_scope.having_values). 
    includes(scoped.includes_values).includes(alt_scope.includes_values). 
    order(scoped.order_values).order(alt_scope.order_values). 
    select(scoped.select_values).select(alt_scope.select_values) 
end 

これをクラスに追加するだけです。

scope :horse_dog_or_trap, horse.or(Event.dog).or(Event.trap) 

もさらに適用範囲を拡張し、こうした:

あなたがスコープで結果的に「店のことができます
Event.horse.or(Event.dog).or(Event.trap) 

:あなたはその後、次のように複数のORクエリを作成する機能が得られます次のようになります。

Event.horse.or(Event.dog).or(Event.trap).today