Rails的单表继承如何工作?

时间:2010-07-10 08:46:36

标签: ruby-on-rails inheritance single-table-inheritance

我有一个用户表和我新创建的老师。老师是用户的子类,所以,我用脚手架生成器生成教师表,比我修改模型做老师是用户的子类。毕竟,我做了一个db:migrate。然后,我去

http://localhost:3000/teachers/new

显示错误:

undefined method `teacherSalary' for #<Teacher:0x103331900>

所以,我的问题是我做错了什么?我想创建一个用户注册页面,用户只能是老师/学生。但是我无法添加教师记录......而且,我去了

http://localhost:3000/users/new

我想要一个允许用户注册其用户为“老师”或“学生”的组合框。但是一切看起来都不像我预期的那样。我需要做什么?非常感谢你的帮助。

3 个答案:

答案 0 :(得分:2)

在您的数据库中,您应该有一个名为users的表。该表应该有一个字符串列,默认情况下称为类型。如果您为此列使用其他名称,则必须使用self.inheritance_column = "column_name"

手动设置继承列名称

在您的应用程序中,您有三个模型,用户,学生和教师。用户像往常一样从ActiveRecord :: Base继承,Student和Teacher都继承自User。

然后,您应该能够实例化新的Teacher和Student对象。在内部,这通过将模型名称写入用户表上的类型字段来工作,然后当您使用Student.find时,它会向SQL添加一个子句,仅返回type ='Student'的行

您可以向User类添加共享行为,例如验证等然后向继承的类添加其他行为。

有关STI如何运作的更全面的描述可以在Martin Fowlers Book(Patterns of Enterprise Application Architecture)中找到。

答案 1 :(得分:2)

我发现这个定义非常方便: STI表示一个表包含多个模型的数据,通常由“类型”列区分。 (“用户”表包含模型“教师”,“”学生“,”员工“,”助理“等)的数据。 在同一个表中保留类似的模型,而不是创建新模型。

多态关联意味着一个模型可以与多个其他模型相关联(注释可以属于post,image,file,user_type ......) 为了防止外键冲突,使用* _id和* _type列而不是仅仅* _id重复关联。

答案 2 :(得分:0)

对于你在这里所拥有的,我不确定STI是否是最好的方式。当存在类似继承的OO并且模型具有相同的属性但行为不同时,通常应该使用STI。在您的情况下,教师和学生可以肯定有一些共享属性,但他们也必然会有不同的属性。
您可能也想尝试多态关联。