2013-03-26 2 views
-1

세 모델이 있습니다 : Event, CommentPhoto입니다. 이벤트에는 has_many :commentshas_many :photos이 있습니다.OR 조건을 가진 여러 내부 조인에서 잘못된 결과가 발생했습니다.

내 목표는 지난 24 시간 동안 새로운 댓글 및/또는 사진을받은 모든 이벤트를 찾는 것입니다.

두 개의 이벤트가 있다고 가정합니다. 하나는 최근 댓글이 있고 다른 하나는 최근 사진이 있다고 가정합니다.

나는 함께 개별적으로 조회 할 경우 단일 결합, 모든 것이 예상대로 작동합니다

Event.joins(:comments).where("comments.created_at >= :today", :today => Time.now.beginning_of_day) 

반환 : [#<Event id: 1>]

Event.joins(:photos).where("photos.created_at >= :today", :today => Time.now.beginning_of_day) 

반환 : [#<Event id: 2>]

을 내가 모두를 결합 할 때 그것을 왜 조인 :

Event.joins(:comments, :photos) 
    .where("comments.created_at >= :today OR photos.created_at >= :today", :today => Time.now.beginning_of_day) 

내가받은 [#<Event id: 2>, #<Event id: 2>] - 두 번 # 2,하지만 # 1 아니? ARel에 의해 생성

은 SQL 그것은이 SQL의 문제입니다

SELECT "events".* 
FROM "events" 
     INNER JOIN "comments" 
       ON "comments"."event_id" = "events"."id" 
     INNER JOIN "photos" 
       ON "photos"."event_id" = "events"."id" 
WHERE (comments.created_at >= '2013-03-25 23:00:00.000000' 
      OR photos.created_at >= '2013-03-25 23:00:00.000000') 

답변

1

입니다 : 당신이 왼쪽 대신 INNER의 가입 가입 지정해야합니다. include는 당신을 위해 그것을 할 것입니다 :

Event.include(:comments, :photos).where(...).uniq 
+0

제안 사항을 오해 할 수도 있지만'.uniq' 만 추가하면 이벤트 # 1과 이벤트 # 2 대신 이벤트 # 2가 한 번만 반환됩니까? – janfoeh

+0

미안하지만. MurifoX가 말했듯이, 당신은 왼쪽 join을해야하고 inner join은하지 말아야합니다. try Event.include (: comments, : photos) .where (...) 솔루션 인 경우 제안을 수정합니다. –

2

내가 때문에 INNER JOIN입니다 생각합니다. 이 쿼리는 photoscomments이 모두 연결된 events 만 가져옵니다.
RDBMS에 INNER 대신 LEFT JOIN을 사용하고 두 결과를 모두 가져올 수 있습니다.

+0

감사합니다. LEFT JOIN이 실제로 효과가 있습니다. 아직도, 나는 설명에 대해 완전히 확신하지 못한다. 'INNER JOIN' 두 개만'photos'와'comments' 둘 모두와 일치하는 행을 얻는다면 왜 single-JOIN 쿼리는 각각 하나만 반환합니까? 이 경우 두 개의 JOIN이있는 쿼리는 # 2가 아닌 두 번 결과가 0이어야합니다. – janfoeh

+0

아마 # 2 사진과 코멘트가 있으십니까? – MurifoX

+0

아니요. 그게 나를 당황하게하는 부분입니다. 'comments'에 가입하면 Event # 1이 나옵니다. '사진 '에 가입하면 이벤트 # 2가 발생합니다. 둘 다 가입하면 이벤트 # 2, 이벤트 # 2가 표시됩니다. – janfoeh

관련 문제