2012-02-05 112 views
0

我有应用程序,其中用户可以有几个不同的配置文件之一。一些配置文件数据总是相同的(如姓名,性别等)。其他领域可能会有所不同(例如,医生可以拥有关于他自己的许可证编号和文字,而患者可以拥有电话号码等)。导轨和多个配置文件

我发现了一种方法,很适合,但仍有一些疑问。我的方法的要点如下:

  1. 用户模型中包含了很多具体的系统数据,通过制定控制和has_one :person

  2. Person模型包含常见的配置文件数据和belongs_to :profile, :polymorphic => true

  3. Doctor/Patient/Admin/etc包含更具体的配置文件数据和has_one :person, :as => :profile

通过这种方法,我可以亲自模型简单检查:

def doctor? self.profile_type == 'Doctor' end

但有几件事情不给我休息一下。

首先是表现。这种方法需要大量额外的连接。例如,为了同时阅读医生的许可证号码,姓名和电子邮件,它将生成2个额外的连接。

第二个是针对个人资料模型(即Doctor)和个人/用户模型的不同ID。当ID = 1的用户与不同的ID具有Patient关系时,会出现这样的情况,但对于所有这些关联的模型具有相同的ID是合乎逻辑的。

也许你们会看到这种方法更多的陷阱?我的情况有没有更好的解决方案?

回答

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 

由于这一个是敞开的,你可以允许网站管理员重新定义需要什么样的领域,增加新的领域,等等,而无需进行架构更改。

+0

感谢您的回应!根据你的建议,多态对我来说仍然是最干净的方法。我不打算在用户同时拥有多个配置文件的情况下。但我同意,会有一些索引问题。看起来没有理想的解决方案。 – tipugin 2012-02-06 04:34:23

+1

理想的解决方案是可以工作的,并且不会在将来给您带来麻烦,就这些! – tadman 2012-02-06 14:36:18