2012-02-06 49 views
0

我试图在Rails 3中构建学生门户,但是我遇到了一些问题。与关系的单表继承

这个想法是有一个用户表,其中包含一个给定的人的所有基本数据。有关示例属性,请参见下面的UML/E-R。

  • 用户既可以是助理学生同时。
  • 助理学生应该从继承用户

这个想法是直接从用户身上继承,像这样。

class User < ActiveRecord::Base 
    # ... 
    def awesome? 
    [true, false].sample 
    end 
    # ... 
end 

class Student < User 
    has_one :student 
    has_many :registered_courses, through: :students 
end 

Student.new.awesome? 

这使得学生模型中的关系很奇怪。 has_many :registered_courses, through: :students

我想最终能做到这样的事情。

student.full_name 
student.pin_code 
student.registered_courses 

一个解决方案是实现手工方法,这样

class Student < User 
    has_one :student 
    def pin_number 
    student.pin_number 
    end 
end 

但它看起来真的很奇怪指学生模型内的学生对象。

有没有更清晰,更好的方法呢?

这里是一个UML/E-R的例子。我试图通过删除不相关的属性来保持这个例子的清洁。这就是为什么注册课程实体的属性如此之少。

uml

+0

为什么table'Student'需要'id'和'user_id'?这是Rails限制吗? – 2012-02-06 02:19:51

+0

'id'不需要。我不确定为什么它在那里。 – Oleander 2012-02-06 02:23:51

+0

总共有2或4张桌子吗?单表继承应该是2 ...(学生和助理应该是同一个用户表)。你的情况看起来像多表继承(如果它是MTI,那么你不会继承模型......) – PeterWong 2012-02-06 02:50:34

回答

0

STI不是这个,你在这里阐述的方式一个很好的选择,因为用户既可以是学生和助手。当您使用STI时,通常会添加一个类型列来指定记录真正属于哪个子类。如果学生和助理都从用户继承,那么这不是一种选择,因为您将被迫为同​​时为助理和学生的人创建重复的用户记录。

我想你最好只是将学生和助理行属于学生,然后将包含在用户中的元素委派回用户对象。

+0

我还有一些如何需要从用户模型继承。用户模型中的所有逻辑都必须在学生或助理内部可访问。 – Oleander 2012-02-06 03:03:52

+0

您可以使用委托使其看起来像用户逻辑位于学生或助理中。例如,在您的学生课程中,您可以委派:ssn,:email,:to =>:user – 2012-02-06 03:11:33

0

我觉得继承在这里是一个坏的举动。如果你想拥有这样的STI,HAS是一个或另一个。

取而代之,将所有逻辑放入User模型中,您的所有数据都在那里。另外因为Student & Assistant不是互斥的,不应该有任何方法会相互覆盖。

为什么不是STI?

STI主要用于包含相同数据但与它们做不同事情的对象。

例如,我有一个包含多个进程(例如构建和测试)的规范。所以我有一个order,其中包含processes

process_1: 
    order_id: 1 
    specification: foo 
    type: build 

process_2: 
    order_id: 1 
    specification: foo 
    type: test 

在这个例子中,改变数据的唯一事情是类型,但由于类型的变化,我知道什么process从规范执行。