我目前的項目允許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 =')。 –