5

特定のモデルからシンボル化されたディープ アソシエーションを取得するユース ケースがあり、外部結合を使用する特定のクエリを実行する必要があります。完全な SQL を手で書くことに頼らずに、どうすればそれを行うことができるでしょうか?

私が望まない答え: 'その副作用は必要ありません) - SQL を自分で記述します (申し訳ありませんが、2013 年です。クロスデータベースのサポートなど...、フェッチするオブジェクトは read_only であり、さらに副作用があります)

私はArelソリューションが欲しいです。モデルの arel_table を使用して SQL 式を構築できることはわかっていますが、結合用の DSL もありますが、モデルの結合メソッドでそれを使用することはできません。

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 がそのような明らかに必要な機能をいつ搭載するのか教えてくれたりしたら、永遠に感謝します。

4

3 に答える 3

9

これは古い質問ですが、検索エンジンで見つけた人のために:

に渡すことができるものが必要な場合は、と.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)

また

構築した結合オブジェクトから を使用し.join_sourcesます。

eng_exp = car.join(engine, Arel::Nodes::OuterJoin).on(car[:engine_id].eq(engine[:id]))
Car.joins(eng_exp.join_sources)
于 2014-03-04T10:29:37.773 に答える
7

この問題に対処することを目的としたブログ投稿を見つけました: 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)
于 2013-02-22T20:05:42.147 に答える
0

依存関係を追加して AREL を完全にスキップしてもかまわない場合は、Ernie Miller の優れた Squeel gemを使用できます。それは次のようなものになります

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

これには、次のように Car モデルを Engine に関連付ける必要があります。

belongs_to :engine
于 2015-07-31T21:39:14.970 に答える