RAILS用户层次结构; class级,协会。 多态?

令我惊讶的是,仍然找到一个明确的答案是多么困难:看起来很常见,我必须把它看错。

我们有用户,他们的授权角色运行类似ROLES =%w [admin moderator老师学生被禁止]

通常建议使用ROLES字段和单表inheritance(如此处 )

class User < ActiveRecord::Base end class Student < User end class Teacher < User end 

但是这会将所有数据放在一个表中。 如果我们对每种用户类型都有一个独特的数据,该怎么办?

 student year:integer request_id:integer portfolio_id:integer status:string ... teachers user_id:integer district:string school:string subject1:string subject2:string specialty:string bio:text ... 

STI提供了像student.specialty和teacher.portfolio_id这样的东西,我们不想要这些东西并且必须阻止它们。

Ruby Way建议抽象基础模型类来处理单独的表:

 class User < ActiveRecord::Base self.abstract = true end class Student < User end class Teacher < User end 

这将允许学生和教师的独特表格。 然而,他警告说,User.find(:all)将不起作用。 此外,还有我们想要的共同属性,这是用户模型的全部要点:

 User username:string email:string password:string role:string 

既然没有User表,那么没有共同的属性?

各种其他答案暗示使用:polymorphic => true:class_name => 'User' ,或者as:所有解释更像是为post和图像添加评论。 这似乎不是一个很好的平行。

我似乎记得至少有一种语言(也许是几个OODB)只使用IS-A关系来inheritance属性。

什么是RAILS方式?

我认为STI在这里做错了。 你有太多事情会被推到一张桌子上。

我宁愿做一个通用的用户模型,持有像电子邮件,名称和每个用户类型这样的常见内容有一个单独的模型(和表)。 因此,教师和学生会引用用户,但有自己的领域。

角色也应该在与用户分开的自己的表中。

像这样引用用户记录:

 class Teacher < AR::Base belongs_to :user end class Student < AR::Base belongs_to :user end class User < AR::Base has_one :teacher has_one :student end