我有4个班 - 病人,医生,人和预约。 Patient和Doctor是Person的子类。任命属于患者,属于医生。
我想写一个AR语句来按病人的姓氏和另一个来排序约会,按医生的姓氏排序,因为所有约会都在可排序的表格中。我对AR查找语句的“顺序”选项中的内容感到困惑。如果我把
:order => 'patient.last_name'
我收到mysql错误 - “未知列'patient.last_name' 这是有道理的,因为没有患者专栏,这是一个patient_id指的是外国“人”对象。当然我可以按person.last_name排序,但我不知道如何指定排序的人 - 医生或病人。
我还应该注意,我正在使用include选项来急切地加载患者和医生。
更新
只有人员表和约会表。病人和医生都是从这个人那里继承的。 patients.last_name不起作用,因为没有患者表。
AR声明是:
find :all,
:include => [:doctor, :patient],
:order => 'something needs to go here'
“需要去的地方”应该是医生的姓氏或患者姓氏的命令。
答案 0 :(得分:1)
你可以这样做:
Appointment.find(:all, :include => {:patient}, :order => 'people.last_name')
您正在做的是同时抓住所有约会及其相关患者。您不必担心患者与医生,因为检索到的所有行都将是患者记录。
为了获得以医生为中心的清单,只需更改:患者为:上述例子中的医生。
编辑:当你急切地加载患者和医生时,我想出了解决方案。它有点复杂。首先,我在空白的rails应用程序中重新创建了4个模型的简单版本,然后尝试使用: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”。后续关联获得了关联和原始表的组合 - “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
现在你可以从任何地方打电话给他们,甚至按你想要的字段排序。
答案 1 :(得分: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。然后您可以ORDER BY last_name,sort_column,结果将根据医生/患者排序值相应地排列在last_name组内。
注意:我今天早上还没有喝咖啡,所以加入可能都是不合时宜的,但你会得到我希望的一般想法。