我有应用程序,用户可以拥有多个不同的配置文件之一。一些个人资料数据总是相同的(如名字和姓氏,性别等)。其他领域可能有所不同(例如,医生可以拥有关于他自己的许可证号码和文本,而患者可以拥有电话号码等)。
我找到方法,非常适合,但仍有一些疑问。我的方法的观点如下:
用户模型包含许多系统特定数据,由Devise和has_one :person
人员模型包含常见的个人资料数据和belongs_to :profile, :polymorphic => true
医生/患者/管理员等包含更具体的个人资料数据和has_one :person, :as => :profile
通过这种方法,我可以简单地检查人物模型:
def doctor?
self.profile_type == 'Doctor'
end
但是有一些事情不能让我休息。
首先是表演。这种方法需要大量额外的连接。例如,为了同时读取医生的许可证号码,姓名和电子邮件,它将生成2个额外的连接。
第二个是特定于配置文件的模型(即Doctor)和Person / User模型的不同ID。有些情况,当ID = 1的用户将具有不同ID的患者关系时,但对于所有这些关联模型具有相同的ID是合乎逻辑的。
也许你们会在这种方法中看到更多的陷阱?对我的情况有没有更好的解决方案?
答案 0 :(得分:3)
你可以在这里使用四种可能有用的基本模式。
<强> Omnirecord 强>
在此模型中,您可以在单个记录中包含所有可能的字段,然后使用STI来区分配置文件类型。这是最简单的实现,但看起来最混乱,因为很少人会填充所有字段。请记住,NULL
字符串字段不占用大量数据库空间,通常每列一位,因此拥有大量数据库空间并不是什么大问题。
可选加入
在此模型中,您可以创建许多可能与不同配置文件类型的链接,例如doctor_profile_id
链接到DoctorProfile,patient_profile_id
链接到PatientProfile,等等。由于每个关系都在特定字段中拼写出来,因此您甚至可以根据需要强制执行外键约束,并且索引很容易。当单个记录需要与其关联的多个不同的配置文件时,这可以派上用场,就像患者也是医生一样。
多态加入
在此模型中,您可以使用:polymorphic
选项链接到特定的个人资料类型和个人资料ID,就像您建议的那样。索引更复杂,外键不可能。您也只能拥有一个且只有一个配置文件。这些往往是一个起点,但当你得到医生+患者的要求时可能会成为麻烦。
键/值存储
在此模型中,您放弃了将事物组织成单个记录的所有工作,而是构建关联的ProfileField和ProfileValue表。 ProfileField标识哪些字段可用于哪种类型的配置文件,例如标签,允许值,数据类型等,而ProfileValue用于存储特定配置文件的特定值。
class User < ActiveRecord::Base
has_many :profile_fields
end
class ProfileField < ActiveRecord::Base
has_many :profile_values
end
class ProfileValue < ActiveRecord::Base
belongs_to :user
belongs_to :profile_field
end
由于这个是全开放的,您可以允许站点管理员重新定义所需的字段,添加新字段等,而无需更改架构。