从 has_many 协会过滤集合?

Filter the collection from has_many association?

我正在尝试 return 一个 teacher 对象及其 .students 的集合,但是 只有 符合条件的学生.这是老师和学生:


Teacher.find_by(name: "John Smith").students
# shows all students for teacher john smith

现在我尝试过滤学生,以便我们生成相同的 Teacher 对象,但 年龄在 20 岁或以上的学生。我认为这会起作用:

Teacher.find_by(name: "John Smith").where('students.age > ?', 20)

NoMethodError: undefined method `where' for #<Teacher:0x00007fae78d292f8>

您的查询应该是:

Teacher.find_by(name: "John Smith").students.where('students.age > ?', 20)

其中 returns ActiveRecord::Relation
find_by 实施:

def find_by
  where(*args).take
end

如您所见,find_by 与 where 相同,但 returns 只有一条记录。此方法应该用于获取 1 条记录,应该使用 where 来获取具有某些条件的所有记录。

经过一些摆弄后,我意识到不可能 return 一个与 Teacher.find_by(name: "John Smith") 完全相同的对象,但只有年龄大于 20 岁的学生,因为这将跨 2 个单独的表进行查询。

我做的简单的事情是

@teacher = Teacher.find_by(name: "John Smith")

# then 
@students = @teacher.students.where('students.age > ?', 20)

即把它分成两行代码就可以了

您可以像这样过滤 has_many

has_many :older_students, -> { where('students.age > ?', 20) }

# Then use it
@students = Teacher.find_by_name('John Smith').older_students