简体   繁体   中英

Rails ActiveRecord scopes with multiple joins and has_one associations

I'm creating some scopes inside of my Job model, which will be used by ActiveAdmin to filter out jobs at various stages of the pipeline.

I'm having to create joins to other tables to gather the relevant info, and this is where I'm running into trouble. I've outline my logic and (non-working) attempts below.

How would I refactor these so that they work properly?

# app/models/job.rb

# where job.survey exists AND job.appointment.appointment_date is in past AND job.quote doesn’t exist

scope :awaiting_quote, -> { joins(:survey).
  joins('LEFT OUTER JOIN quotes ON quote.job_id = jobs.id').
  joins('LEFT OUTER JOIN appointments ON appointment.job_id = jobs.id').
  where('appointment.appointment_date < :current_time', { current_time: Time.current }).
  where('survey.id IS NOT NULL').
  where('quote.id IS NULL')
}

# where job.quote exists AND job.quote_accepted is false

scope :awaiting_acceptance, -> { joins(:quote).
  joins('LEFT OUTER JOIN appointments ON quote.job_id = jobs.id').
  where('appointment.appointment_date < :current_time', { current_time: Time.current }).
  where('quote.id IS NOT NULL').
  where('quote_accepted = :quote_accepted', { quote_accepted: false })
}

has_one :quote
has_one :survey
has_one :appointment
has_one :surveyor, through: :appointment
accepts_nested_attributes_for :appointment, :allow_destroy => true
accepts_nested_attributes_for :survey, :allow_destroy => true

# app/models/quote.rb

belongs_to :job

# app/models/survey.rb

belongs_to :job

# app/models/appointment.rb

belongs_to :job
belongs_to :surveyor

# app/models/surveyor.rb

has_many :appointments
has_many :jobs, through: :appointments

As there are no conflicts in the column names between tables, the trick is to join all the tables, and just perform where methods on the combined data.

scope :awaiting_quote, -> {
  joins(:survey, :quote, :appointment).
  where('quote IS NULL').
  where('appointment_date < :current_time', current_time: Time.current)
}

scope :awaiting_acceptance, -> {
  joins(:quote, :appointment).
  where('appointment_date < :current_time', current_time: Time.current).
  where('quote IS NOT NULL').
  where('quote_accepted = :quote_accepted', quote_accepted: false)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM