设计STI与MTI对比单独的表格

时间:2011-08-14 06:42:18

标签: ruby-on-rails devise sti

我有一个使用devise进行身份验证的rails 3.1项目。

我有几种用户类型,每种类型都在数据库中占用非常不同的字段。我为每个模型设置了不同的模型,但是模型之间存在足够的重叠功能,例如消息传递,这对于拥有单个模型是有意义的。在处理不同类型的用户之间的消息传递时,这尤其是一个问题。

我应该将它们全部作为单独的表格放置还是将它们移动到单个表格中?考虑到我们将一直在查找用户这一事实,多表继承确实没有多大意义。加入它只是太昂贵了。

在表格中为每个用户类型添加所有未使用的列只是感觉很脏。

思想?

1 个答案:

答案 0 :(得分:1)

就我个人而言,我不认为未使用的列是非常重要的,但如果它真的困扰你,你可能想尝试非正统的解决方案。您是否考虑过“分拆”不同类型用户不常见的所有属性?我在谈论使用attr_bucket之类的插件。

基本上你会在你的db表中添加额外的列:

t.text :non_common_attributes

然后在每个不同的用户模型(继承自公共类)中,你会有类似的东西:

class UserType1 < User
  attr_bucket :non_common_attributes => [:first, :second, :third]
end

class UserType2 < User
  attr_bucket :non_common_attributes => [:fourth, :fifth]
end

您将使用这些属性,就像它们以正常方式定义一样,但是当您将模型保存到数据库中时,所有这些属性都将通过YAML序列化并存储在:non_common_attributes列中。当您再次加载模型时,它们将被透明地反序列化。

有一些注意事项,例如你不想通过任何bucketed属性搜索用户(因为你不能索引这些属性)等等。但在你的情况下它可能只是什么你在追求。我不会太担心序列化和反序列化的成本,它可能不会成为一个问题,因为你不可能同时保存/加载数千个用户。

事实上,我使用了一个类似的解决方案(但是手动滚动而不是使用宝石),其中大多数属性都需要加密。我只是将所有属性存储在一起并对存储桶进行加密 - 这是一种享受。

相关问题