mardi 4 juillet 2017

Get parent objects without active childs

I've two models, Doctor and Clinic where a doctor has_many clinics.

Clinic have doctor_id and a boolean active field.

What I want:

I want to get all doctors which does not have any active (active field is true) clinics i.e. either doctor does not have any clinics or does not have any clinics where active field is true.

What I've tried so far:

Try 1:

scope :incomplete_doctors, -> { includes(:clinics)
                                .where("( doctor_clinics.id IS NULL ) OR
                                        ( doctor_clinics.id IS NOT NULL AND
                                            doctor_clinics.active=?)", false )
                              }

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

Try 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));

Success:

I'm able to achieve desired output using following method, but I want to achieve this using a SQL query.

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

Aucun commentaire:

Enregistrer un commentaire