Вы можете сделать это:
Appointment.find(:all, :include => {:patient}, :order => 'people.last_name')
То, что вы делаете - это захватывает все встречи и связанных с ними пациентов одновременно. Вам не нужно беспокоиться о пациентах против врачей, потому что все извлеченные строки людей будут записями пациентов.
Чтобы получить список, ориентированный на доктора, просто измените: пациента на: доктора в приведенном выше примере.
РЕДАКТИРОВАТЬ: Я нашел решение, когда вы хотите загрузить как пациентов, так и врачей. Это становится немного сложным. Сначала я воссоздал простую версию ваших 4 моделей в пустом приложении rails, а затем попытался запустить поиск с помощью :order => 'patients.name'
:
Appointment.find(:all, :include => [:patient, :doctor], :order => 'patients.name')
Конечно, если произошел сбой, но он также выполнил запрос SQL:
SELECT
"appointments"."id" AS t0_r0,
"appointments"."name" AS t0_r1,
"appointments"."doctor_id" AS t0_r2,
"appointments"."patient_id" AS t0_r3,
"appointments"."created_at" AS t0_r4,
"appointments"."updated_at" AS t0_r5,
"people"."id" AS t1_r0,
"people"."name" AS t1_r1,
"people"."type" AS t1_r2,
"people"."created_at" AS t1_r3,
"people"."updated_at" AS t1_r4,
"doctors_appointments"."id" AS t2_r0,
"doctors_appointments"."name" AS t2_r1,
"doctors_appointments"."type" AS t2_r2,
"doctors_appointments"."created_at" AS t2_r3,
"doctors_appointments"."updated_at" AS t2_r4
FROM "appointments"
LEFT OUTER JOIN "people" ON "people".id = "appointments".patient_id AND ("people"."type" = 'Patient' )
LEFT OUTER JOIN "people" doctors_appointments ON "doctors_appointments".id = "appointments".doctor_id AND ("doctors_appointments"."type" = 'Doctor' )
ORDER BY patients.name
Теперь мы можем видеть, как rails формирует запрос, подобный этому. Первая ассоциация, которая использует данную таблицу, получает имя таблицы напрямую - "people". Последующие ассоциации получают комбинацию ассоциации и оригинальную таблицу - "doctor_appointments".
Это может показаться немного беспорядочным, но этот звонок дает вам распоряжение пациентов:
Appointment.find(:all, :include => [:patient, :doctor], :order => 'people.name')
А этот дает вам по приказу врачей:
Appointment.find(:all, :include => [:patient, :doctor], :order => 'doctors_appointments.name')
Конечно, в моем примере у меня просто было простое поле имени для каждого человека, и вы будете использовать вместо него «last_name». Но ты получил идею. Это работает для вас?
ОДИН ПОСЛЕДНИЙ РЕДАКТИРОВАТЬ:
Я бы поместил их в средства поиска, чтобы вам не приходилось связываться с именами таблиц где-либо еще в вашем коде. Я бы сделал это так:
class << self
def order_by_patient(field='last_name')
find(:all, :include => [:patient, :doctor], :order => "people.#{field}")
end
def order_by_doctor(field='last_name')
find(:all, :include => [:patient, :doctor], :order => "doctors_appointments.#{field}")
end
end
Теперь вы можете вызывать их из любого места и даже сортировать по полю, которое хотите.