2010-01-19 36 views
2

我有4個班 - 病人,醫生,人,和約會。病人和醫生是Person的子類。約會屬於患者,屬於醫生。如何訂購通過在Ruby on Rails的同一個基類繼承多個子類的屬性?

我想寫一個AR語句排序患者的姓氏和另一個約會在醫生的姓氏排序,因爲所有的任命將在排序表。我有點困惑,要放什麼東西在AR發現語句的「命令」選項。如果我把

:order => 'patient.last_name' 

我得到一個MySQL錯誤 - 「未知列‘patient.last_name’ 這是有道理的,因爲沒有病人列,它是一個patient_id指外國‘人’的對象當然。我可以通過person.last_name排序,但我不確定如何指定按醫生或患者排序的類型。

我還應該注意,我正在使用include選項來加載患者和醫生。

UPDATE

世上只有一個人表和約會表。病人和醫生繼承人。因爲沒有患者表,所以patient.last_name將不起作用。

的AR聲明:

find :all, 
       :include => [:doctor, :patient], 
       :order => 'something needs to go here' 

的「東西需要去這裏」應該是一個聲明或者醫生的姓氏或病人的姓氏訂購。

+0

您在使用STI?另外,你可以發佈整個失敗的AR查找或named_scope嗎?如果有病人表,那麼你可能應該這樣做:order =>'patients.last_name'(複數),但我們不能確定你的基礎表是什麼樣的... – hgmnz 2010-01-19 19:57:46

+0

我更新了我的問題 – Tony 2010-01-19 20:49:42

回答

1

你可以這樣做:

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如何形成這樣的查詢。使用給定表的第一個關聯直接獲取表名 - 「人員」。隨後的關聯會獲得關聯和原始表的組合 - 「doctors_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 

現在你可以從任何地方打電話給他們,甚至根據你想要的字段排序。

+0

看我的編輯以上。我的問題是更多關於當急於加載時做什麼,但是我會嘗試加載一個,因爲這可能是一個解決方案。 – Tony 2010-01-19 20:50:45

+0

嗨託尼 - 我更新了你的筆記,所以現在它應該做你提到的一切。 – 2010-01-19 22:26:41

0

我想你可能需要使用手動加入,而不是包括。

Active Record Querying Guide on Joining Tables

然後,您可以相應地確立這些爲表名的別名,和秩序。

find.all(:joins => 'LEFT OUTER JOIN people dr ON dr.id = appointments.id' 
    :order => dr.last_name 
) 

或類似的數據庫。

或者,您可以添加保存整數的「分類」欄中。所有的醫生都有一個1,病人有一個0.然後你可以根據醫生/病人排序值,然後在last_name組內排列ORDER BY last_name,sort_column。

注:我還沒有我的咖啡今天上午又使加盟可能是所有出怪人的,但你希望的總體思路。

相關問題