如何使用ActiveRecord存储/建模用户/ facebook用户/ linkedin用户等?

时间:2010-01-21 00:24:34

标签: activerecord data-modeling

我的应用

  • “普通”用户:通过典型注册页面的用户
  • facebook(FB)用户:来自Facebook的那些用户
  • “FB-normal”用户:可以使用电子邮件/密码* FB连接
  • 进行登录的用户

此外,还有一些其他openID-ish登录方法(我不认为openID本身是可以接受的,因为它没有链接帐户并允许第三方特定功能(发布到Twitter,添加一个FB帖子等等))

那么,我该如何建模呢?

现在我们有#facebook_user的User类?定义 - 但它对“FB-normal”用户来说变得混乱 - 加上所有的验证变得非常棘手且难以解释。此外,还有像#deliver_password_reset这样的方法!这对于仅限Facebook的用户来说是没有意义的。 (这很蹩脚)

我已经考虑过STI(User :: Facebook,User :: Normal,User :: FBNormal等)这使验证超级光滑,但它不能扩展到其他连接类型,以及它们之间的所有排列... User :: FacebookLinkedInNormal(wtf?)用一堆模块来做这件事我认为会很糟糕。

还有其他想法吗?

2 个答案:

答案 0 :(得分:0)

你正遇到其中一枚object-relational impedance mismatch地雷。

Facebook和LinkedIn都通过使用非关系键/值存储来解决这个问题。 Facebook使用Cassandra,LinkedIn使用Project Voldemort

如果您不受关系模型约定的约束(例如,给定表的所有行具有相同的列),您可以获得更大的灵活性并改变每行的属性。但是这样做会牺牲关系模型的一些优势(例如,给定表的所有行都具有相同的列)。

在RDBMS中,我会使用Class Table Inheritance来构建它。

答案 1 :(得分:0)

我会将这些问题分开,似乎在一张表中保留具有完全不同字段的记录是没有意义的。

只有一个用户模型/表不保存任何凭据,并使其与帐户/登录方法具有has_many关系,您可以使用STI对不同类型进行建模。

class User < AR::B
  has_many :accounts
end

class Account < AR::B;end

class PasswordAccount < Account;end 

class GoogleAccount < Account;end

class FacebookAccount < Account;end

…