web-dev-qa-db-ja.com

LEFT OUTERは、Rails 3

私は次のコードを持っています:

@posts = Post.joins(:user).joins(:blog).select

すべての投稿を検索し、それらと関連するユーザーとブログを返すことを目的としています。ただし、ユーザーはオプションです。つまり、INNER JOINが生成する:joinsは、大量のレコードを返していません。

代わりにこれを使用してLEFT OUTER JOINを生成するにはどうすればよいですか?

85
Neil Middleton
@posts = Post.joins("LEFT OUTER JOIN users ON users.id = posts.user_id").
              joins(:blog).select
111
Neil Middleton

これを行うには、includesRailsガイド

Post.includes(:comments).where(comments: {visible: true})

結果:

SELECT "posts"."id" AS t0_r0, ...
       "comments"."updated_at" AS t1_r5
FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id"
WHERE (comments.visible = 1)
75
WuTangTan

私は squeel gem の大ファンです:

Post.joins{user.outer}.joins{blog}

innerouterの両方の結合、および多態的なbelongs_to関係のクラス/タイプを指定する機能をサポートしています。

11
plainjimbo

つかいます eager_load

@posts = Post.eager_load(:user)
10
Ricardo

デフォルトでは、ActiveRecord::Base#joinsに名前付き関連付けを渡すと、INNER JOINが実行されます。 LEFT OUTER JOINを表す文字列を渡す必要があります。

ドキュメント から:

:joins-"LEFT JOIN comments ON comments.post_id = id"(まれに必要)などの追加結合のSQLフラグメント、:includeオプションで使用されるのと同じ形式の名前付き関連付け。関連付けられたテーブル、または文字列と名前付き関連付けの両方を含む配列。

値が文字列の場合、レコードはテーブルの列に対応しない属性を持つため、読み取り専用で返されます。 :readonly => falseを渡してオーバーライドします。

8
DBA

Activerecordには left_outer_joins メソッドがあります。次のように使用できます。

@posts = Post.left_outer_joins(:user).joins(:blog).select
7
Ahmad Hussain

良いニュース、Rails 5はLEFT OUTER JOIN。クエリは次のようになります。

@posts = Post.left_outer_joins(:user, :blog)
4
Dex
class User < ActiveRecord::Base
     has_many :friends, :foreign_key=>"u_from",:class_name=>"Friend"
end

class Friend < ActiveRecord::Base
     belongs_to :user
end


friends = user.friends.where(:u_req_status=>2).joins("LEFT OUTER JOIN users ON users.u_id = friends.u_to").select("friend_id,u_from,u_to,u_first_name,u_last_name,u_email,u_fbid,u_twtid,u_picture_url,u_quote")
0
Jigar Bhatt