简体   繁体   English

如何在Ruby on Rails中继承自同一基类的多个子类的属性排序?

[英]How can I order by attributes of multiple subclasses that inherit from the same base class in Ruby on Rails?

I have 4 classes - Patient, Doctor, Person, and Appointment. 我有4个课程-病人,医生,人员和预约。 Patient and Doctor are subclasses of Person. 患者和医生是“人”的子类。 Appointment belongs to Patient and belongs to Doctor. 预约属于患者,属于医生。

I want to write an AR statement to sort appointments by the patient's last name and another to sort by the doctor's last name, as all appointments will be in a sortable table. 我想编写一个AR语句,以便按患者的姓氏对约会进行排序,而另一个要按医生的姓氏进行排序,因为所有约会都将在可排序的表中。 I am a bit confused as to what to put in the "order" option of the AR find statement. 对于在AR find语句的“ order”选项中放入什么,我有些困惑。 If I put 如果我放

:order => 'patient.last_name'

I get a mysql error - "Unknown column 'patient.last_name' Which makes sense because there is no patient column, it is a patient_id referring to a foreign "person" object. Of course I can sort by person.last_name but I am not sure how to specify which type of person to sort by - doctor or patient. 我收到一个mysql错误-“未知列'Patient.last_name',这是有道理的,因为没有耐心的列,它是一个指向外国“ person”对象的Patient_id。我可以按person.last_name进行排序,但我不是确定如何指定要按哪种类型的人员分类-医生还是患者。

I should also note that I am using the include option to eager load the patient and doctor. 我还应注意,我正在使用include选项来急切地加载患者和医生。

UPDATE UPDATE

There is only a person table and a appointments table. 只有一个人表和一个约会表。 The patient and doctor inherit from the person. 病人和医生都继承人。 patients.last_name will not work because there is no patients table. Patient.last_name将不起作用,因为没有患者表。

The AR statement is: AR语句为:

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

The 'something needs to go here' should be a statement to order by either the doctor's last name or the patient's last name. “需要去这里的东西”应该是医生姓氏或患者姓氏的订购说明。

You can do this: 你可以这样做:

Appointment.find(:all, :include => {:patient}, :order => 'people.last_name')

What you're doing is grabbing all the appointments, and their associated patients at the same time. 您正在做的是同时获取所有约会及其相关的患者。 You don't have to worry about patients vs doctors because all the people rows retrieved will be patient records. 您不必担心患者与医生的关系,因为检索到的所有人员行都是患者记录。

In order to have a doctor-centric list, just change :patient to :doctor in the above example. 为了拥有以医生为中心的列表,只需在上述示例中将:Patient更改为:doctor即可。

EDIT: I figured out the solution when you eager load both patients and doctors. 编辑:当您渴望为患者和医生提供服务时,我便找到了解决方案。 It gets a little complex. 它有点复杂。 First, I recreated a simple version of your 4 models in a blank rails app, then tried to run the find with :order => 'patients.name' : 首先,我在空白的Rails应用中重新创建了4个模型的简单版本,然后尝试使用:order => 'patients.name'运行查找:

Appointment.find(:all, :include => [:patient, :doctor], :order => 'patients.name')

Of course if failed, but it also spit out the SQL query it attempted: 当然,如果失败,它还会吐出它尝试的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

Now we can see how rails forms a query like this. 现在我们可以看到Rails如何形成这样的查询。 The first association to use a given table gets the table name directly - "people". 使用给定表的第一个关联直接获取表名称-“ people”。 Subsequent associations get a combo of the association and original table - "doctors_appointments". 后续关联将获得关联和原始表的组合-“ doctors_appointments”。

It may seem a little messy, but this call gives you ordered by patients: 似乎有些混乱,但是此呼叫为您提供了按患者排序的命令:

Appointment.find(:all, :include => [:patient, :doctor], :order => 'people.name')

And this one gives you ordered by doctors: 这是医生给您的命令:

Appointment.find(:all, :include => [:patient, :doctor], :order => 'doctors_appointments.name')

Of course, in my example I just had a simple name field for each person, and you'll be using "last_name" instead. 当然,在我的示例中,我只是为每个人提供了一个简单的名称字段,您将改为使用“ last_name”。 But you get the idea. 但是你明白了。 Does this work for you? 这对您有用吗?

ONE LAST EDIT: 最后编辑:

I would put these in finders, so you don't need to mess with the table names anywhere else in your code. 我会将它们放在查找器中,因此您无需在代码中的其他任何地方弄乱表名。 I'd do it like this: 我会这样:

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

Now you can call them from anywhere, and even sort by the field you want. 现在,您可以从任何地方调用它们,甚至可以按所需字段进行排序。

I think you might need to use a manual join rather than an include. 我认为您可能需要使用手动联接而不是包含。

See the Active Record Querying Guide on Joining Tables . 请参见有关联接表Active Record查询指南

You can then create an alias for the table names, and order on these accordingly. 然后,您可以为表名创建一个别名,并对其进行相应的排序。

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

Or something similar for your database. 或类似的数据库。

Alternatively, you can add a "sort" column that holds an integer. 另外,您可以添加一个包含整数的“排序”列。 All doctors have a 1, patients have a 0. You can then ORDER BY last_name, sort_column, and the results will be arranged accordingly within the last_name group based on the doctor/patient sort value. 所有医生的数字都为1,患者的数字为0。然后您可以按ORDER BY last_name,sort_column进行排序,结果将根据医生/患者的排序值在last_name组中进行相应排列。

Note: I haven't had my coffee yet this morning so that join is possibly all out of wack, but you get the general idea I hope. 注意:今天早上我还没有喝咖啡,所以加入的想法可能不尽人意,但是您希望我能有个大致的想法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不继承ActiveRecord :: Base的类中使用Paperclip gem for Rails? - How can I use Paperclip gem for Rails in a class that does not inherit from ActiveRecord::Base? 在ruby on rails中,如何验证一系列值的多个属性? - In ruby on rails, how can I validate multiple attributes for a range of values? 如何在Ruby on Rails中将特定属性的使用限制为特定子类 - How to restrict use of specific attributes to specific subclasses in Ruby on Rails 如何加载不直接从Rails 5中的Rails验证器类继承的自定义验证器? - How can I load a custom validator which does not directly inherit from a Rails validator class in Rails 5? 我怎样才能在轨道上的红宝石中按相关性进行订购 - how can i order by relevance in ruby on rails 如何在Ruby on Rails中使用Base64编码? - How can I use Base64 encoding in Ruby on Rails? 如何通过关联记录的属性订购Rails集合? - How can I order a Rails collection by the attributes of associated records? Rails通过多个表中的属性订购商品 - Rails order posts by attributes from multiple tables ruby类方法可以从另一个类继承吗? - Can a ruby class method inherit from another class? Rails:如何使模型从父模型“继承”属性? - Rails: How to get a model to “inherit” attributes from a parent model?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM