我有以下方法:
def self.sap_qualified(start_at, stop_at, zip)
course_ids = Course.where('sap_qualifying IS true OR sap_renewing IS true').collect{|c| c.id}
if course_ids.any?
course_class_ids = CourseClass.where(course_id: course_ids).collect{|c| c.id}
if course_class_ids.any?
joins(:class_registrations).
joins(:primary_billing).where("postal_code =?", zip).
where(:class_registrations => {course_class_id: course_class_ids}).
where('class_registrations.score ~ ? AND CAST(class_registrations.score as int) >= ? AND class_registrations.exam_completed_at >= ? AND class_registrations.exam_completed_at <= ?', '^[0-9]', 80, start_at.to_date.beginning_of_day, stop_at.to_date.beginning_of_day)
else
...
...如果用户包含邮政编码(第三个参数),则可以预期该方法有效。但是,如果用户将邮政编码字段留空,则我想在不使用邮政编码的join语句的情况下运行查询。
我可以做类似的事情
if !zip.blank?
one query...
else
same query as above, but with the joins(:primary_billing).where("postal_code =?", zip)...
...但是那感觉很古怪,并且违反了大约十二个DRY主体。
答案 0 :(得分:1)
查询中的每个ActiveRecord语句都返回一个Relation,您可以将其保存到中间变量:
if course_class_ids.any?
relation = joins(:class_registrations)
if zip.present?
relation = relation.joins(:primary_billing).where("postal_code =?", zip)
end
relation = relation.where(:class_registrations => {course_class_id: course_class_ids}).
where('class_registrations.score ~ ? AND CAST(class_registrations.score as int) >= ? AND class_registrations.exam_completed_at >= ? AND class_registrations.exam_completed_at <= ?', '^[0-9]', 80, start_at.to_date.beginning_of_day, stop_at.to_date.beginning_of_day)
else