假设我有两个模型,两个模型都有一个name
字段:
class Student < ActiveRecord::Base
end
class Teacher < ActiveRecord::Base
end
现在我想找到所有名为'Joe'的学生和老师。我的想法:
name = 'Joe'
Student.where(name: name) + Teacher.where(name: name)
但是当我添加其他类型的模型并且还有name
字段并且我想要搜索它们时,事情变得很难看:
name = 'Joe'
Student.where(name: name) + Teacher.where(name: name) + Manager.where(name: name) + ...
有更好的方法吗?理想情况下,我想要做的是,定义一个模块Person
,然后只需:
Person.where(name: name)
注意:由于其他原因,无法更改架构。
答案 0 :(得分:0)
解决方案可能是以适合此类查询的方式定义数据模型。如果您确实需要按名称处理所有“人”,那么您应该拥有一个带有角色或属性的Person数据模型来定义他们的“类型”。
答案 1 :(得分:0)
当您谈到定义Person
模块时,您正走在正确的轨道上。查看database normalization以了解如何最好地定义模型。
由于教师和学生都是人,但角色不同,您应该将它们存储在同一个模型中,但添加一个允许您选择 教师或的字段只是学生。像这样的东西(伪代码):
Person
:name (string)
:role (string)
通过这种方式,您可以编写诸如“找到所有具有教师角色的John的人”或“查找所有名为Sue且具有任何角色的人”的查询。
使用这种模型,您需要在该角色字段上强制执行值,以便人们无法输入他们想要的任何内容 - 否则,您最终会得到一些说“学生”和其他人说的记录例如,“同学”。 (你可以更进一步,将角色存储在一个单独的表中,但这是另一个讨论!)
答案 2 :(得分:0)
你必须使用rails继承,你可以这样做:
class Person < ActiveRecord::Base
# shared person methods
end
class Student < Person
end
class Teacher < Person
end
您还必须有一个名为persons
的表,其中一列名为type
(字符串)。
在此之后,您的学生和老师将进入persons
表(您可以删除原始表)。
您可以使用Person.where(name: name)
查询所有学生和人员,并将包括所有学生和教师。并且您可以Student.all
只获得学生,就像普通模特一样。