简体   繁体   English

具有多个联接和has_one关联的Rails ActiveRecord范围

[英]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. 我在Job模型中创建了一些作用域,ActiveAdmin将使用这些作用域在管道的各个阶段过滤掉作业。

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. 由于表之间的列名没有冲突,所以诀窍是联接所有表,然后对组合数据执行where方法。

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)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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