2011-11-02 2 views
1

I했습니다있어 내 레일에서 다음 모델 설정 3 응용 프로그램 :레일에 수를 포함하는 경우와 조인 테이블 조인 중첩 된

class User << AR::Base 
    has_many :groups 
end 

class Group << AR::Base 
    belongs_to :user 
    has_many :memberships 
    has_many :contacts, :through => :memberships 
end 

class Membership << AR::Base 
    belongs_to :group 
    belongs_to :contact 
end 

class Contact << AR::Base 
    has_many :memberships 
    has_many :groups, :through => :memberships 
end 

나는이 쿼리의 많은 오프로드하려고 데이터베이스를 가능한 한 많이하지만 나는 (잠재적으로 많은) 그룹을 통해 x 개 이상의 연락처를 가진 사용자 목록을 얻으려고합니다.

루비/레일스 코드를 사용하여 문제없이 수행 할 수 있지만 모든 데이터가 메모리로로드되므로 큰 데이터 세트의 경우 고통이 될 수 있습니다.

x = 4 # or whatever 
User.all.select{ |u| u.groups.collect(&:contacts).flatten.uniq.size > x } 

내가 좋아하는 일을 해봤 다음하지만 아무 소용이 :

또한
User.joins(:groups => :contacts).where('count(contacts.id) > ?', x) 

연락처가

우측에있는 점의 모든 종류의 구별되어야하는 것이 좋을 것이다 방향은 끝내 주겠지 만, SQL은 내 강한 포인트 중 하나가 아니며 그것은 내가 오늘 뇌가 죽은 것 같습니다.

답변

8

조금이 고민 한 나는 약간의 도움을 얻었다 그래서

User.select("users.*, count(distinct contacts.id) as num").joins(:groups => :contacts).group('users.id').having('num > 10') 
처럼 내 쿼리를 완료 할 수 있었다