我目前的项目允许Doctors
有许多Patients
与我能做到以下几点:Rails的多态关联:getter和setter方法
dennis = Patient.create
frank = Doctor.create
dennis.update(doctor: frank)
dennis.doctor #=> frank
frank.patients #=> [dennis, ...]
但现在我想补充一类医院,也可以有很多病人。我不想再为Hostpital
级别添加has_many
,因为Patient
“所有权”可能会再次发生变化,最终我的患者模型将被外键域填满,除了其中一个外,其余都将为空。多态关联似乎正是我一直在寻找:一个Patient
通过无论是Doctor
可以“拥有”或Hospital
:
class Patient < ActiveRecord::Base
belongs_to :owner, polymorphic: true
end
class Doctor < ActiveRecord::Base
has_many :patients, as: :owner
end
class Hospital < ActiveRecord::Base
has_many :patients, as: :owner
end
这使我们可以做到以下几点:
dennis = Patient.create
frank = Doctor.create
dennis.update(owner: frank)
dennis.owner #=> frank
frank.patients #=> [dennis, ...]
但是,我们不能拨打dennis.doctor
返回frank
。我知道业主可能并不总是Doctor
类的实例,但我当前的许多代码都使用#doctor
和#doctor=
方法。所以我想我可以定义他们:
class Patient < ActiveRecord::Base
belongs_to :owner, polymorphic: true
def patient=(patient)
self.owner_id = patient.id
self.owner_type = "Patient"
end
def patient
return nil unless self.owner
self.owner.class == Patient ? self.owner : nil
end
end
这似乎工作正常,但这种关联仍然没有反映在我的数据库。我有一些引用patients.doctor
的自定义SQL查询。这现在抛出Mysql2::Error: Unknown column 'patients.doctor'
与多态关联。
有没有更好的方法可以实现呢?在这一点上,回顾我所有的代码和sql查询,将.doctor
更改为.owner
将会非常耗时。
TL; DR试图从的has_many到多态关联切换,但我想保持方便的getter和setter方法(以及我的数据库中的关联)通过的has_many关系提供。
任何帮助表示赞赏!
为了什么缓存这是值得的,我强烈建议避免多态关联。在数据库中执行它们非常困难(数据完整性),因为您失去了拥有外键约束的能力。如果您为每个可能的拥有者拥有外键,那么您可以使用外键并检查约束。这在我的工作项目中非常有效地完成(也许有一天我们会使其开源)。我们也有你所描述的getter和setter方法('owner'和'owner =')。 –