私は次のコードを持っています:
@posts = Post.joins(:user).joins(:blog).select
すべての投稿を検索し、それらと関連するユーザーとブログを返すことを目的としています。ただし、ユーザーはオプションです。つまり、INNER JOIN
が生成する:joins
は、大量のレコードを返していません。
代わりにこれを使用してLEFT OUTER JOIN
を生成するにはどうすればよいですか?
@posts = Post.joins("LEFT OUTER JOIN users ON users.id = posts.user_id").
joins(:blog).select
これを行うには、includes
Railsガイド :
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)
私は squeel gem の大ファンです:
Post.joins{user.outer}.joins{blog}
inner
とouter
の両方の結合、および多態的なbelongs_to関係のクラス/タイプを指定する機能をサポートしています。
つかいます eager_load
:
@posts = Post.eager_load(:user)
デフォルトでは、ActiveRecord::Base#joins
に名前付き関連付けを渡すと、INNER JOINが実行されます。 LEFT OUTER JOINを表す文字列を渡す必要があります。
ドキュメント から:
:joins
-"LEFT JOIN comments ON comments.post_id = id
"(まれに必要)などの追加結合のSQLフラグメント、:include
オプションで使用されるのと同じ形式の名前付き関連付け。関連付けられたテーブル、または文字列と名前付き関連付けの両方を含む配列。値が文字列の場合、レコードはテーブルの列に対応しない属性を持つため、読み取り専用で返されます。
:readonly => false
を渡してオーバーライドします。
Activerecordには left_outer_joins メソッドがあります。次のように使用できます。
@posts = Post.left_outer_joins(:user).joins(:blog).select
良いニュース、Rails 5はLEFT OUTER JOIN
。クエリは次のようになります。
@posts = Post.left_outer_joins(:user, :blog)
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")