groupor 와 결합 된 has_many 테이블에 대한 내부 조인을 수행하는 uniq것은 잠재적으로 매우 비효율적이며 SQL에서는 EXISTS상관 하위 쿼리와 함께 사용하는 세미 조인으로 더 잘 구현됩니다 .
이를 통해 쿼리 옵티마이 저는 올바른 project_id를 가진 행이 있는지 확인하기 위해 vacancies 테이블을 조사 할 수 있습니다. 해당 project_id가있는 행이 1 개인 지 백만 개인지는 중요하지 않습니다.
Rails에서 그렇게 간단하지는 않지만 다음을 통해 달성 할 수 있습니다.
Project.where(Vacancies.where("vacancies.project_id = projects.id").exists)
마찬가지로 공석이없는 모든 프로젝트를 찾습니다.
Project.where.not(Vacancies.where("vacancies.project_id = projects.id").exists)
편집 : 최근 Rails 버전에서는 existsarel에 위임되는 것에 의존하지 말라고 알려주는 폐기 경고가 표시 됩니다. 이 문제를 다음과 같이 수정하십시오.
Project.where.not(Vacancies.where("vacancies.project_id = projects.id").arel.exists)
편집 : 원시 SQL이 불편한 경우 다음을 시도하십시오.
Project.where.not(Vacancies.where(Vacancy.arel_table[:project_id].eq(Project.arel_table[:id])).arel.exists)
arel_table예를 들어 다음 과 같이의 사용을 숨기는 클래스 메서드를 추가하여이를 덜 지저분하게 만들 수 있습니다 .
class Project
def self.id_column
arel_table[:id]
end
end
... 그래서 ...
Project.where.not(
Vacancies.where(
Vacancy.project_id_column.eq(Project.id_column)
).arel.exists
)