2012-09-07 4 views
3

두 개 모두 Micropost 모델 내부에 관계를 반환하는 코드가 있습니다.OR 대신에 AND 관계를 AND

scope :including_replies, lambda { |user| where("microposts.in_reply_to = ?", user.id)} 

def self.from_users_followed_by(user) 
    followed_user_ids = user.followed_user_ids 
    where("user_id IN (?) OR user_id = ?", followed_user_ids, user) 
end 

내가 r1 = Micropost.including_replies(user)를 실행하면 내가받을 다음과 같은 SQL 두 결과와의 관계 :

SELECT `microposts`.* FROM `microposts` WHERE (microposts.in_reply_to = 102) ORDER BY 
microposts.created_at DESC 

내가 r2 = Micropost.from_users_followed_by(user)을 실행할 때 나는 다음과 같은 SQL 한 결과에 관계 얻을 :

SELECT `microposts`.* FROM `microposts` WHERE (user_id IN (NULL) OR user_id = 102) ORDER 
BY microposts.created_at DESC 

이제는 관계를 병합 할 때 r3 = r1.merge(r2) 결과가 0이되었지만 3을 기대하고있었습니다. 그 이유는 SQL은 다음과 같습니다이다 :

SELECT `microposts`.* FROM `microposts` WHERE (microposts.in_reply_to = 102) AND 
(user_id IN (NULL) OR user_id = 102) ORDER BY microposts.created_at DESC 

은 이제 필요 (microposts.in_reply_to = 102) OR (user_id IN (NULL) OR user_id = 102) 입니다 내가 OR 대신 병합 관계에 AND이 필요합니다.

이 방법이 있습니까?

답변

1

레일과 직접 연결되지 않습니다. Rails는 ActiveRelation (범위가 지정된) 객체를 OR과 병합하는 방법을 제공하지 않습니다. 그 이유는 ActiveRelation에는 조건 (WHERE 절에 설명 된 내용)뿐만 아니라 OR과 병합하는 조인 및 기타 SQL 절이 잘 정의되어 있지 않기 때문입니다.

Arel을 직접 (ActiveRelation이 위에 구축 됨) 사용하거나을 사용하여 Arel 기능을 DSL (더 편리 할 수 ​​있음)을 통해 노출 할 수 있습니다. Squeel을 사용하면 ActiveRelations를 병합 할 수 없습니다. 그러나 Squeel은 Sifters도 제공합니다 (다른 SQL 절이없는 조건).이 조건은 사용할 수 있습니다. 스코프를 sifters로 재 작성하는 것이 포함됩니다.