LEFT OUTER는 Rails 3에서 결합됩니다.


86

다음 코드가 있습니다.

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

이는 모든 게시물을 찾고 해당 게시물과 관련 사용자 및 블로그를 반환하기위한 것입니다. 그러나 사용자는 선택 사항 INNER JOIN이므로 :joins생성 하는 사용자가 많은 레코드를 반환하지 않습니다.

LEFT OUTER JOIN대신 이것을 생성하기 위해 어떻게 사용 합니까?


답변:


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

3
사용자가없는 게시물 만 원하면 어떻게합니까?
mcr

24
@mcr@posts = Post.joins("LEFT OUTER JOIN users ON users.id = posts.user_id").joins(:blog).where("users.id IS NULL").select
리누스 서양 협 죽도

1
선택에 매개 변수가 필요하지 않습니까? 이게 안돼 select('posts.*')?
Kevin Sylvestre

Rails 3에서는 이것이 조인을 실제로 제어하고 무슨 일이 일어나고 있는지 정확히 알 수있는 유일한 방법입니다.
Joshua Pinter

75

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)

14
내 테스트 includes에서 조인이 아니라 연결을 얻기 위해 별도의 쿼리를 수행합니다. 따라서 N + 1을 피하지만 하나의 쿼리에서 레코드를 가져 오는 JOIN과 같은 방식은 아닙니다.
Kris

7
@Kris 당신 말이 맞아요. includes함수가 사용하는 상황에 따라 두 가지를 모두 수행 하기 때문에주의해야 할 사항입니다. Rails 가이드는 섹션 12의 전체 내용을 읽는 것보다 더 잘 설명합니다 : guides.rubyonrails.org/ …
WuTangTan 2013

4
때문에 부분적으로 만 질문에 대한 대답 includes대신 2 개 쿼리를 생성 할 것이다 JOIN당신이 필요가없는 경우 WHERE.
Rodrigue

14
를 추가하지 않으면 Rails 4에서 경고가 생성됩니다 references(:comments). 또한 이로 인해 반환 된 모든 주석이으로 인해 메모리에 즉시로드됩니다 includes.
Derek 이전

2
이를 더욱 "Railsy"로 만들려면 : Post.includes(:comments).where(comments: {visible: true}). 이렇게하면 references.
마이클

11

저는 squeel gem열렬한 팬입니다 .

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

innerouter조인을 모두 지원할 뿐만 아니라 다형 적 belongs_to 관계에 대한 클래스 / 유형을 지정하는 기능도 지원합니다 .



8

기본적 ActiveRecord::Base#joins으로 명명 된 연결 을 전달 하면 INNER JOIN이 수행됩니다. LEFT OUTER JOIN을 나타내는 문자열을 전달해야합니다.

에서 문서 :

:joins- " LEFT JOIN comments ON comments.post_id = id"(드물게 필요함) 와 같은 추가 조인에 대한 SQL 조각 , :include옵션에 사용 된 동일한 형식의 명명 된 연관 , 연관된 테이블에서 INNER JOIN을 수행하거나 두 문자열의 혼합을 포함하는 배열 및 명명 된 연관.

값이 문자열이면 테이블의 열과 일치하지 않는 속성을 가지므로 레코드는 읽기 전용으로 반환됩니다. 패스 :readonly => false재정에.


7

있습니다 left_outer_joins의 액티브있는 방법은. 다음과 같이 사용할 수 있습니다.

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

1
이것은 포스터가 요구하는 Rails 3에는 존재하지 않는 것 같습니다.
cesoid

옳은; 이것은 Rails 5.0.0에서 도입되었습니다.
올리 베넷

4

좋은 소식이 있습니다. Rails 5는 이제 LEFT OUTER JOIN. 이제 쿼리는 다음과 같습니다.

@posts = Post.left_outer_joins(:user, :blog)

0
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")
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.