2012-03-21 3 views
3

프로젝트 목록이 있고 작업이있는 프로젝트 만 표시하려고합니다. has_many 관계에 count를 가진 조건을 사용할 수 있습니까?has_many 릴레이션에 count가있는 조건을 사용할 수 있습니까?

# get my project list 
Project.includes(:tasks).where(...) 

class Project < ActiveRecord::Base 
    has_many :tasks 

class Task < ActiveRecord::Base 
    belongs_to :project 

현재 루프를 통해이 작업을 수행하고 있지만 이것이 올바른 방법이라고 생각하지 않습니다.

+1

내가 [여기]를 비슷한 질문을 한 (http://stackoverflow.com/questions/8227557/activerecord-find-categories-which-contain-at-least-one-item). 그것이 당신을 도울 수 있기를 바랍니다. – ZelluX

답변

1

프로젝트에 대한 작업로드가 이미 마음에 들면 다음 명령문을 사용하여 작업이 포함 된 프로젝트를 가져올 수 있습니다.

# get my project list 
Project.includes(:tasks).where("tasks.id IS NOT NULL") 

includesLEFT OUTER JOIN를 사용하기 때문에이 작동합니다.

반면에 작업을 열망하지 않으려면 joins을 사용할 수 있습니다.이 경우에는 INNER JOIN이 사용됩니다.

Project.joins(:tasks).where(...) 
1

includes 지시문은 데이터베이스 연결 방식이 아닌 JOIN이 아닌 이러한 연관성을 단순히로드하는 것으로 나타납니다. 따라서 추가 작업 없이는 실제로 조건을 수행 할 수 없습니다.

비례가 잘되는 한 가지 방법은 연결의 counter_cache 기능을 사용하는 것이므로 항상 작업 수를 숫자로 계산해야합니다. 쿼리 성능을 향상시키기 위해 인덱스를 추가 할 수도 있습니다.

Project.where('id IN (SELECT DISTINCT project_id FROM tasks)') 

이 아마도 당신이 project_id에 인덱스를 가지고 당신의 tasks 표에 상당히 저렴 작동하는지 확인하기 :

대안은 아마 같은 시도하고 tasks 테이블에서 역방향으로 작동하는 것입니다.

+0

당신은 이것을 위해'counter_cache'가 필요 없습니다. 'includes' 지시어가 사용되기 때문에 생성 된 SQL은 LEFT OUTER JOIN을 사용합니다. 그것은 null이 아닌 검사를하는 문제입니다. 사용자가'join '을 사용하면 시나리오가 훨씬 간단 해집니다. 나는 아래의 나의 대답에서 이것을 논의했다. –

+0

나는 당신이 필요없는 것을 적재하지 않는 것이 낫다는 것을 알고 있습니다. 프로젝트에 kabillion 작업이있는 경우 제한없이 모든 작업을로드하면 응용 프로그램이 손상 될 수 있습니다. – tadman

+0

나는 그것이 열렬한 로딩을 선택하는 동안 취해야 할 일반적인주의 사항이다. –

1

이 트릭하지 왜 제목이 확실하지에서 알 수 있듯이 문제는 간단 경우 별도의 규정이없는 한,

Project.joins(:tasks) 

에 가입이 안 될 것입니다 가입, 따라서 어떤 결과를 제외 누구의 프로젝트에는 작업이 없으므로 아마도 당신이 필요로하는 것이 전부입니다 ... 개의 프로젝트가 표시됩니다. 당신은 몇 가지 조건이있는 경우

(예를 들어, 그 상태 활성화 프로젝트) 당신은 또한

Project.joins(:tasks).where("status = 'active') 

같은 조건을 지정할 수 있습니다 아니면 내가 뭔가를 놓친?

관련 문제