我正在尝试在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的示例。我试图通过删除不相关的属性来保持这个例子的清洁。这就是注册课程实体中属性如此之少的原因。
答案 0 :(得分:0)
STI不是一个很好的选择,因为你在这里阐述它,因为用户既可以是学生也可以是助手。在使用STI时,通常会添加一个类型列来指定记录真正属于哪个子类。如果学生和助理都从用户继承,那么这实际上不是一个选项,因为您将被迫为同时为助理和学生的人创建重复的用户记录。
我认为你最好只使用属于Student的Student和Assistant行,然后将User中包含的元素委托给User对象。
答案 1 :(得分:0)
我觉得继承在这里是一个糟糕的举动。如果你有这样的STI, HAS 就是其中之一。
而是将所有逻辑抛入User
模型,无论如何你的所有数据都存在。加上Student
&amp; Assistant
不是互斥的,不应该有任何方法可以互相覆盖。
为什么不是STI?
STI主要用于包含相同数据的对象,但与它们做不同的事情。
例如,我有一个包含多个进程的规范(例如build和test)。所以我的order
包含processes
。
process_1:
order_id: 1
specification: foo
type: build
process_2:
order_id: 1
specification: foo
type: test
在此示例中,数据中唯一发生变化的是类型,但由于类型更改,我知道要从规范中执行process
。