2012-01-15 10 views
1

結合を実行した後に複数の列を選択しようとしています。私はクエリで引用符の間にSQLを記述しないでActiveRecordを使用する方法を見つけることができませんでした。(避けたいのですが)複数の列に結合して選択する

"Arel"を使って複数の列を選択できました。しかし、私はArelを直接使うべきかどうか、あるいはARと同じように達成する方法があるかどうかについてはあまりよく分かりません。

これらはARELのコードです:

l = Location.arel_table 
r = Region.arel_table 

postcode_name_with_region_code = l.where(l[:id].eq(location_id)).join(r).on(l[:region_id].eq(r[:id])).project(l[:postcode_name], r[:code]) 

このクエリを実行した後、私はの線に沿って何かを返すしたいと思います: (擬似コード)を

"#{:postcode_name}, #{:code}" 
  1. ARを使用して同じクエリを実行する方法はありますか?
  2. Arelに固執すると、SelectManagerクラスの値をどのように取得して上記のクエリが返されますか?

事前のおかげで、

答えて

0

は、任意のSQLを記述することなく、ARを使用して、モデルや団体を想定しては、次のとおりです。

モデル/ region.rb

class Region < ActiveRecord::Base 
    has_many :locations 
end 

モデル/ location.rb

class Location < ActiveRecord::Base 
    belongs_to :region 
end 

あなたは確かに行うことができます:

postcode_name_with_region_code = Location.where(:id=>location_id).includes(:region).collect{|l| "#{l.postcode_name}, #{l.region.code}"} 

これは、クエリを実行してから(私は複数のレコードが返される可能性と仮定しているので、それは配列を返すことに注意してください)あなたの結果をフォーマットするためにルビーを使用します。配列の1つの項目だけが必要な場合は、配列を参照するためにarray.firstメソッドを使用できます。

あなたは熱心な負荷協会もできたし、その結果から、あなたの文字列を構築:

my_loc = Location.find(location_id, :include=>:region) 

postcode_name_with_region_code = "#{my_loc.postcode_name}, #{my_loc.region.code}" 
+0

あなたが答えてくれてありがとうマイク。 これは、パフォーマンスの面では、包含とは対照的に結合を行うのに有効ではないという別の疑問をもたらします。このクエリではパフォーマンスが大幅に低下することはありませんが、includeを使用するとDBに2回クエリを実行することがわかりました。 – Digger

+0

この場合、結合によって実際には何も購入されません。試してみたい場合は、.includes(...)を.joins( "JOIN locations.region_id ON regions.id")に置き換えてください。 2番目の照会は、地域のコードを照会するcollectステートメントの結果です。私はあなたにも試してみたいと思っているならば、アソシエーションの熱心なロードを活用するソリューションを追加しました。 – miked

+0

ありがとう、私はそれを行ってあげるよ。 ARで再生した後、これがクエリになりました: 'Location.joins(:region).where(:id => location_id).select( 'locations.postcode_name、regions.code' ).map {| l | "#{l.postcode_name}、#{l.code}"} ' – Digger

0
predicate = Location.where(:id=>location_id).includes(:region) 
predicate.ast.cores.first.projections.clear 
predicate.project(Location.arel_table[:postcode_name], Region.arel_table[:code])