2

说我有以下型号

Course has_many :students
Course has_many :lectures
Lecture has_many :topics

如果我做:

courses = Course.find(:all, :includes => [:students, {:lectures => :topics}])

我得到所有的课程、学生、讲座和主题。

我只想获得包含某些学生的课程,然后对于每门课程,我只想获得某些讲座,但每个讲座的所有主题。

因此,假设我想获得一个名为“约翰”的学生的所有课程,但只有每门课程的 2 次最新讲座以及这 2 次讲座的所有主题。

我不明白如何将这些过滤器应用于上面的原始查询。

希望获得有关如何执行此类查询的一些指导。

4

1 回答 1

0

您将使用查询 API 来修改预先加载的内容:

courses = Course.includes(:students, {:lectures => :topics}).
                 where(:students => {:name => 'John'})

只为每门课程获取 2 个最近的讲座是一个重大挑战,我不相信有一个跨数据库解决方案可以在没有递归子查询来确定排名的情况下做到这一点(这将是非微不足道的数据量并取消急切加载的任何好处)。您可以确定最近的(MAX),然后是之后的下一个最近的(比原始 MAX 早的 MAX),但这种方法也将非常低效且非常混乱。

如果您可以选择特定的 DBMS,这可能是可行的。或者,选择不同的策略来确定“最近”(例如,每门课程的缓存日期,或经过的固定时间量)。

更新

假设您只需急切加载所有讲座并手动选择前 2 个,您可以使用as_json序列化程序执行此操作(对于 JSON):

courses = ... # same as above
courses.each do |c|
  c.lectures = c.lectures.sort_by(&:happens_at)[-1..-2]
end.as_json(:include => [:students, {:lectures => {:include => :topics}}])
于 2013-04-11T20:53:13.580 回答