1

В настоящее время я настраиваю область в моей модели Rails, которая будет использоваться ActiveAdmin. Объем, который я хочу построить, должен найти каждый Job, который в прошлом имел survey_date, с подарком Job.survey и отсутствием Job.quotes.Rails Область действия модели ActiveRecord с присоединениями к ассоциациям has_many

Вот сокращенный вариант моей Job модели:

has_many :quotes 
has_many :surveys 

scope :awaiting_quote, lambda { joins(:surveys, :quotes).where('survey_date < :current_time AND surveys.id IS NOT NULL AND quotes.id IS NULL', { current_time: Time.current }) } 

Как я должен изменить масштаб так, чтобы он правильно находит revelant Job записи?

+1

Пожалуйста, обратите внимание, 'joins' создаст внутреннее соединение, которое означает, что' quotes.id IS NULL' не имеет никакого влияния, и эти работы никогда не будет отображаться попробовать 'включает в себя (: опросы,: котировки) .где (» survey_date <: current_time AND survey.id IS NOT NULL И quotes.id IS NULL ', {current_time: Time.current}) 'это создаст 2 LEFT OUTER JOIN s и может функционировать лучше для вас. Вот большой [статья] (http://blog.bigbinary.com/2013/07/01/preload-vs-eager-load-vs-joins-vs-includes.html) об загрузке ассоциации и о том, как работают методы – engineersmnky

ответ

3

Вы можете создать левые внешние соединения с помощью joins, вам просто нужно быть более явным.

scope :awaiting_quote, -> { joins(:surveys). 
    joins('LEFT OUTER JOIN quotes ON quotes.job_id = jobs.id'). 
    where('survey_date < :current_time', { current_time: Time.current }). 
    where('quotes.id IS NULL') 
} 

Вам не нужно surveys.id IS NOT NULL поскольку успешное внутреннее соединение не будет включать в себя нулевые идентификаторы.

Возможно, имеет смысл разделить их на две отдельные области: :has_survey и :without_quote, которые затем могут быть объединены в метод.

def self.awaiting_quote 
    Job.has_survey.without_quote 
end 
+0

Отлично, спасибо! – gosseti

Смежные вопросы