4

TableA2つのテーブルがありTableB、結合テーブルを介して多対多の関係にあると仮定しますTableABJoin。ARel 3を使用して、との完全結合を実行するクエリを生成したいと思いTableAますTableB

私が生成したいクエリは、これらの線に沿ったものでなければなりません:

SELECT a.id, b.code
FROM TableA as a, TableB as b

これにより、テーブルAとBが完全に結合されます。

明示的なSQL文字列を記述せずに取得できた最も近い方法は、外部結合をハックすることです。

part_a = TableA.arel_table
part_b = TableB.arel_table
query = part_a.join(part_b, Arel::Nodes::OuterJoin).on('1=1').project(part_a[:id], part_b[:code]).to_sql

これにより、次のSQLが生成されます。

SELECT "TableA"."id", "TableB"."code" FROM "TableA" LEFT OUTER JOIN "TableB" ON 1=1

コンポーネントを除外する.onと、末尾にNULLが表示されます。

SELECT "TableA"."id", "TableB"."code" FROM "TableA" LEFT OUTER JOIN "TableB" NULL

ARelの左外部結合をハッキングせずに、適切な完全結合を生成する、または少なくとも同じ結果を生成するためのより合理的な方法はありますか?

4

2 に答える 2

5

実際には、内部結合と外部結合(LEFT OUTER)のみをサポートするarelを使用して、完全外部結合(および右外部結合)を実行することはできません。

これが気に入らなかったので、arel 3-0-stable(3.2.13 railsアプリケーションに取り組んでいます)を更新して、右および完全な外部結合もサポートするようにしました。それらを追加することは、文書化されていないコードでも非常に簡単でした。それは非常に簡単なので、試してみても問題はありません。

ここに私のプルリクエストを見つけることができます:https
://github.com/rails/arel/pull/202 そしてここにブランチを持つ更新されたリポジトリを見つけることができます:https ://github.com/Fire-Dragon-DoL/arel / tree /3-0-right-full-outer-join

これをGemfileに追加することで、これをRailsアプリケーションで簡単に使用できます。

gem 'arel', '~> 3.0.3.4', github: 'Fire-Dragon-DoL/arel', branch: '3-0-right-full-outer-join'

ここに構文例を見ることができます:

class Cat < ActiveRecord::Base
  has_many :cat_diseases
end
class Disease < ActiveRecord::Base
  has_many :cat_diseases
end

class CatDisease < ActiveRecord::Base
  belongs_to :cat
  belongs_to :disease

  def self.all_diseases_for_cat(cat)
    cat_diseases = self.arel_table
    diseases     = Disease.arel_table

    scoped
    .joins(
      cat_diseases.join(diseases, Arel::Nodes::RightOuterJoin)
                    .on(cat_diseases[:disease_id].eq(diseases[:id]))
      .join_sources
    )
    .where(
      cat_diseases[:cat_id].eq(cat.id)
      .or(cat_diseases[:cat_id].eq(nil))
    )
  end
end
于 2013-07-31T00:05:52.710 に答える
0

SQLで結合を記述します。その明確で正常に動作します:

part_a = TableA.arel_table
part_b = TableB.arel_table
query = part_a.joins('LEFT OUTER JOIN "TableB"').other_scopes.to_sql
于 2012-08-23T16:31:44.167 に答える