【发布时间】:2017-12-08 15:57:21
【问题描述】:
我有两个模型,Doctor 和 DoctorClinic 其中一个 doctor has_many clinics。
doctor.rb:
has_many :clinics, class_name: 'DoctorClinic', dependent: :destroy
doctor_clinic.rb
belongs_to :doctor
DoctorClinic 有 doctor_id 和一个布尔值 active 字段。
我想要什么:
我想获取所有没有任何活动(active 字段为true)诊所的doctors。如果一个医生有两个诊所,其中一个处于活动状态,另一个处于非活动状态,则不应选择医生。
如果出现以下情况,将选择医生记录,
- 根本没有诊所
- 如果有任何诊所但都处于非活动状态,即所有诊所都有
activefalse。
如果出现以下情况,将不会选择医生,
- 有任何活跃的诊所。
到目前为止我所做的尝试:
尝试 1:
scope :incomplete_doctors, -> { includes(:clinics)
.where("( doctor_clinics.id IS NULL ) OR
( doctor_clinics.id IS NOT NULL AND
doctor_clinics.active=?)", false )
}
尝试 2:
scope :incomplete_doctors, -> { where("id NOT IN (?)", self.includes(:clinics)
.where("( doctor_clinics.doctor_id IS NULL ) OR
( doctor_clinics.doctor_id IS NOT NULL AND
doctor_clinics.active=?)", false )
.select(:id))
}
尝试 3:
SELECT "doctors".* FROM "doctors"
LEFT OUTER JOIN "doctor_clinics" ON "doctor_clinics"."doctor_id" = "doctors"."id"
WHERE ( ( doctor_clinics.id IS NULL ) OR
( doctor_clinics.id IS NOT NULL AND
doctor_clinics.active='f'))
GROUP BY doctors.id
HAVING 'true' <> ANY(array_agg(DISTINCT doctor_clinics.active::TEXT));
成功:
我可以使用以下方法实现所需的输出,但我想使用 SQL 查询来实现。
def active_clinics
clinics.active_clinics # active_clinics is a scope in Clinic model while give all active clinics
end
def self.incomplete_doctors
(Doctor.all.map { |d| d unless d.active_clinics.present? }).compact
end
【问题讨论】:
-
这行得通吗?
left_outer_joins(:doctor_clinics).where( 'doctor_clinics.id = ? OR doctor_clinics.active = ?', nil, false )范围为Doctor.unassociated -
不。当有两个
clinics,一个处于活动状态,另一个处于非活动状态时,它会失败。在这种情况下,不应选择医生。我刚刚在问题中添加了更多信息。 -
@Md.FarhanMemon,另外,
left_outer_joins不起作用(至少在 Rails 3 中),includes等效于left_outer_join。所以,我将该范围更新为{includes(:clinics).where( 'doctor_clinics.id = ? OR doctor_clinics.active = ?', nil, false ) }
标签: sql ruby-on-rails ruby postgresql ruby-on-rails-3