2017-11-18 12 views
0

これはかなり単純なものです。私は間違っています。私は3つのテーブルを一緒に結合しようとしています。groupには、locationの行を参照するlocation_idinfoと同じになるinfo_idが含まれています。Rails joinは結合されたテーブルから値を返しません

は、ここに私のコードです:

@groups = Group.joins(
    'INNER JOIN location on location.id = "group".id', 
    'INNER JOIN info on info.id = "group".id' 
) 

これがエラーなしで動作しているようですが、私は戻って取得していますすべては私のgroupテーブルの列です。私はここで間違って何をしていますか?

P.S.私の団体はlocationinfo belongs_to groupです。あなたはgroupsテーブルにlocation_idinfo_idを持っていることを言うとき、グループlocationhas_oneinfo

答えて

1

目的の列を選択するために選択タグを追加するだけです。

Group.joins(:location, :info).select("location.*, info.*") 

特別な条件が必要な場合は、クラスを追加することもできます。

Group.joins(:location, :info).select("location.*, info.*").where("locations.id = conditions.id") 
+0

私は '.select'を追加して何も変更しませんでした。もう一度エラーは表示されませんが、まだ情報なしでグループのリストを取得しています。私はこれを実行しました 'res = Group.joins( 'location.id =" group ".id'のINNER JOINの場所)select( '" group "。*"、 "location。*") ' –

1

が、これはあなたがGroupbelongs_to関連を持っているつもりことを意味します。

前提条件の: Groupモデルが持っている必要があります。

belongs_to :location 
belongs_to :info 

LocationInfoを持っている必要があります。あなたの質問のために

has_one :group 

を、これが期待されています。 ActiveRecordでは、Relationは呼び出し元のオブジェクトを返します。この場合はGroupです。

ご利用の場合のために、私はあなたが権利を得るために、このアプローチが必要になると思いますが、作業に参加:

問合せ:この後

@groups = Group.joins(:location, :info) 
# "SELECT `groups`.* FROM `groups` INNER JOIN `locations` ON `locations`.`id` = `groups`.`location_id` INNER JOIN `infos` ON `infos`.`id` = `groups`.`info_id`" 

、あなたは情報と場所を得るために、各グループに反復することができます@groups.map { |group| [group.location, group.info] } これは正しい位置と情報を与えます。

最適化:[group.location, group.info]は、場所と情報を取得するために再度クエリを行います。あなたは場所と情報データが含まれるように元のクエリを変更することで、これを最適化することができます。

@groups = Group.joins(:location, :info).includes(:location, :info) 
0

レール/ ARで我々はincludesjoinsを持っています。

joinsを使用しています。 SQLが示すように、それはGroupを選択するだけです。 Groupの結果が必要な場合はjoinsを使用しますが、LocationInfoまでクエリしたい場合もあります。

あなたのケースであると思われるすべての情報を使用する場合は、詳細を表に表示するのと同じように、includesも使用する必要があります。

# @groups = Groups.includes(:locations, :info) results an left outer join 
@groups = Groups.joins(:locations, :info).includes(:locations, :info) # results inner join 

このようなことをすると、追加のdbコールは作成されません。しかし、joinsを使用すると、複数のクエリ(N + 1)が使用されます。

- @groups.each do |group| 
    tr 
    td = group.id 
    td = group.location.lat 
    td = group.info.description 

あなたのプロジェクトを最適化するN + 1個のクエリがあるかどうかを確認するには、弾丸の宝石を使用します。

Google Rails includes vs joinsの場合は、そのトピックに関する詳細情報があります。

+0

実際にはありません。 INNER結合を使用する本来の目的は、主に結合された表の行が存在する行を取得することです。 INNERに参加することで、私が戻ってくる「グループ」は、それと同等の場所と情報があることを排他的に確認できます。 「含む」だけではそれができません。 'group.location'、' group.info'は非常に便利に失敗します – kiddorails

+0

@kiddorails:便宜的に失敗しますか? –

+0

@kiddorailsしかし私は訂正していますが、実際にはどちらも内部結合を使用していました。問題について読んでみる必要があります。それで、内部結合にするために必要なものも含める必要があります。 –

関連する問題