得到 parent objects 没有活跃的孩子
Get parent objects without active childs
我有两个模型,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
字段。
我想要的:
我想获得所有 doctors
没有任何活动(active
字段是 true
)诊所。如果一位医生有两个诊所,其中一个是活跃的,另一个是不活跃的,那么不应选择医生。
如果
将选择医生记录
- 根本没有诊所
- 如果有任何诊所但都处于非活动状态,即都有
active
false
.
医生不会被选中,如果
- 有任何活跃的诊所。
到目前为止我尝试过的:
尝试 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
像这样的东西应该在纯 SQL
中起作用
SELECT *
FROM doctors
WHERE NOT EXISTS (
SELECT 1
FROM doctor_clinics
WHERE
doctor_clinics.doctor_id = doctors.id
AND doctor_clinics.active = true
)
您应该可以将它与 find_by_sql
一起使用:
Doctor.find_by_sql(SQL)
没有 Rails 3 个项目来实际测试它;-)
我有两个模型,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
字段。
我想要的:
我想获得所有 doctors
没有任何活动(active
字段是 true
)诊所。如果一位医生有两个诊所,其中一个是活跃的,另一个是不活跃的,那么不应选择医生。
如果
将选择医生记录- 根本没有诊所
- 如果有任何诊所但都处于非活动状态,即都有
active
false
.
医生不会被选中,如果
- 有任何活跃的诊所。
到目前为止我尝试过的:
尝试 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
像这样的东西应该在纯 SQL
中起作用SELECT *
FROM doctors
WHERE NOT EXISTS (
SELECT 1
FROM doctor_clinics
WHERE
doctor_clinics.doctor_id = doctors.id
AND doctor_clinics.active = true
)
您应该可以将它与 find_by_sql
一起使用:
Doctor.find_by_sql(SQL)
没有 Rails 3 个项目来实际测试它;-)