ActiveRecord:可搜索的问题

时间:2015-05-28 23:02:48

标签: ruby-on-rails activerecord

问题

假设我有两个模型,两个模型都有一个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)

注意:由于其他原因,无法更改架构。

3 个答案:

答案 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只获得学生,就像普通模特一样。