2013-02-22 22 views
5

特定のモデルから象徴的なディープアソシエーションを取得するこのユースケースがあり、外部ジョインを使用する特定のクエリを実行する必要があります。 SQLを手作業で書くのではなく、どうしたらいいですか?Arel:シンボルを使用した外部外部結合

回答を希望しません: - を使用しています(深い関連付けは非常にうまく解決されません(.csludes(:cars => [:windows、:engine => [:ignition] ..... works) - 自分自身でSQLを書く(申し訳ありませんが、2013年、クロスデータベースのサポートなど...、フェッチするオブジェクトはread_onlyで、より多くの副作用があります)

私はArelソリューションを持っていたいと思います。モデルからarel_tableを使用してSQL式を作成できますが、ジョイン用のDSLもありますが、何らかの理由でモデルのjoinメソッドで使用できません。

car = Car.arel_table 
engine = Engine.arel_table 

eng_exp = car.join(engine).on(car[:engine_id].eq(engine[:id])) 
eng_exp.to_sql #=> GOOD! very nice! 
Car.joins(eng_exp) #=> Breaks!! 

なぜこれがうまくいかないのは私を超えています。私は何が欠けているのか正確にはわからない。しかし、それは私が現在持っている解決策に最も近いものです。誰かが私の事例を完成させる手助けをしたり、素敵な回避策を教えたり、Railsにいつ必然的に必要な機能が含まれているか教えてもらえれば、私の永遠の感謝を得ることができます。

答えて

6

私はこの問題に対処することを目的としているブログの記事を見つけました:これ(と私自身のテスト)に基づいてhttp://blog.donwilson.net/2011/11/constructing-a-less-than-simple-query-with-rails-and-arel/

、次はあなたの状況のた​​めに働くべきでは:

car = Car.arel_table 
engine = Engine.arel_table 

sql = car.project(car[Arel.star]) 
     .join(engine, Arel::Nodes::OuterJoin).on(car[:engine_id].eq(engine[:id])) 

Car.find_by_sql(sql) 
+0

:これは車のモデルはそうのようなエンジンに関連付けられることを必要とするであろう

Car.joins{engine.outer}.where(...) 

ようなものになるだろう恐れ、私の唯一の問題は、アソシエーションキーの以前の知識である(私は普通のAR内部結合のような、それに関するよりすぐれた解決策を望む)。しかし、これははるかに質問への最良の答えです、私はすでにそれに基づいて解決策を考案しました。再びThx。 – ChuckE

6

これは古いです質問、しかし、検索エンジンを通してそれを見つける誰の利益のために:

あなたが.joinsに渡すことができます何かをしたい場合は、あなたが.create_join.create_onを使用できます:

join_on = car.create_on(car[:engine_id].eq(engine[:id])) 
eng_join = car.create_join(engine, join_on, Arel::Nodes::OuterJoin) 

Car.joins(eng_join) 

OR

あなたの構築から.join_sourcesを使用したオブジェクトの参加:あなたはErnie Miller's excellent Squeel gemを使用することができ、依存関係を追加し、完全にARELをスキップしてもかまわない場合

eng_exp = car.join(engine, Arel::Nodes::OuterJoin).on(car[:engine_id].eq(engine[:id])) 
Car.joins(eng_exp.join_sources) 
0

を。私は、まあ、これは私たちが今まで買ってあげるの答えに最も近い

belongs_to :engine