带关系的单表继承
我正在尝试在 Rails 3 中构建一个学生门户,但遇到了一些问题。
这个想法是拥有一个用户表,其中包含给定人员的所有基本数据。有关示例属性,请参阅下面的 UML/ER。
- 用户可以同时是助理和学生。
- 助理和学生应该继承自用户。
这个想法是直接从 User 继承,就像这样。
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/ER 示例。我试图通过删除不相关的属性来保持这个示例的干净。这就是注册课程实体中属性如此之少的原因。
I'm trying to build a student portal in Rails 3, but I'm having some problem.
The idea is to have a users table that contains all basic data for a given person. See the UML/E-R below for example attributes.
- A user can be both an Assistant and a Student at the same time.
- Assistant and Student should inherit from User.
The idea was to inherit directly from the User, like this.
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?
This makes the relations in the student model very strange.has_many :registered_courses, through: :students
I want to be able to do something like this in the end.
student.full_name
student.pin_code
student.registered_courses
One solution would be to implementing the method by hand, like this
class Student < User
has_one :student
def pin_number
student.pin_number
end
end
But it looks really strange to refer to a student object inside the student model.
Is there a clearer, better way of doing this?
Here is an example UML/E-R. I've tried to keep this example clean by removing non relevant attributes. That is why there are so few attributes in the registered course entity.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于您在这里所阐述的方式,STI 并不是一个好的选择,因为用户既可以是学生,也可以是助手。当您使用 STI 时,通常会添加一个类型列来指定记录真正属于哪个子类。如果学生和助理都继承自用户,那么这确实不是一个选择,因为您将被迫为既是助理又是学生的人创建重复的用户记录。
我认为您最好只拥有属于学生的学生行和助理行,然后将用户中包含的元素委托回用户对象。
STI is not a good choice for this the way that you have articulated it here, since users can be both students and assistants. When you are using STI, you generally add a type column to specify which subclass the record really belongs to. If both Student and Assistant inherit from User, then that really isn't an option, since you'd be forced to create duplicate User records for someone who is both an Assistant and a Student.
I think you'd be better off simply having Student and Assistant rows that belong_to a Student, and then delegating the elements that are contained in User back to the User object.
我觉得继承在这里是一个糟糕的举动。如果您将患上这样的性传播感染,那么它必须是其中之一。
相反,将所有逻辑都放入
User
模型中,无论如何,所有数据都在那里。再加上Student
&Assistant
并不相互排斥,不应该有任何方法会相互覆盖。为什么不使用 STI?
STI 主要适用于包含相同数据但执行不同操作的对象。
例如,我有一个包含多个进程(例如构建和测试)的规范。所以我有一个包含
流程
的订单
。在此示例中,数据中唯一发生变化的是类型,但由于类型发生了变化,我知道要根据规范执行什么
过程
。I feel like Inheritance is a bad move here. If you're going to have STI like this it HAS to be one or the other.
Instead throw all your logic into the
User
model, all your data is there anyway. Plus sinceStudent
&Assistant
aren't mutually exclusive there shouldn't be any methods that will override each other.Why not STI?
STI is mainly meant for objects that contain the same data, but does different things with them.
For example, I have a specification that contains multiple processes(ex. build and test). So I have a
order
that containsprocesses
.In this example the only thing that changes in the data is the type, but because the type changes I know what
process
to perform from the specification.