2013-04-11 143 views
2

说我有以下型号ActiveRecord的查询过滤嵌套模型

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

如果我做的:

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

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

我想只有具有一定的学生他们,然后为每个课程只希望得到一定的讲课回来课程,但所有的主题为每个讲座。

所以说我想用一个名为“约翰”的学生,但只有2个最近的讲座为每个课程和所有的主题为那些2个讲座的所有课程。

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

想了解如何执行这些查询的一些指导。

+0

进出口使用的轨道:

UPDATE

假设你是罚款只是预先加载所有的讲座和手动选择顶部2,你可以使用as_json串行做到这一点(对JSON) 3.2 – 2013-04-11 20:49:24

+0

我建议使用gem“squeel”(https://github.com/ernie/squeel)。它具有更直观的语法,你可以在github找到你要找的文档 – benams 2013-04-11 20:50:39

+0

你在看什么领域来确定演讲是否是'最近的'? – PinnyM 2013-04-11 20:51:30

回答

0

你会使用查询API修改什么是渴望加载:

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

刚刚获得每门课程2个最近的演讲是一大挑战,我不相信这是一个跨数据库解决方案将在没有递归子查询的情况下执行此操作来确定排名(这将是重要数据量的主要性能消耗,并取消任何加载的好处)。您可以确定最近的(MAX),然后再确定最近的那个(MAX比先前的MAX早),但这种方法也是非常低效且非常混乱的。

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

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}}]) 
+0

谢谢,如果我正在做这个查询返回一个JSON blob,我将如何构建它与最新的讲座。 ['code'] courses = Course.where(:students => {:name =>'John'}) courses.each do | course | 当然[:most_recent] = course.lectures.order(:happens_at)。首先 当然[:next_recent] = course.lectures.order(:happens_at)[1] 端 [/'code'] 似乎别扭虽然 – 2013-04-12 13:16:31

+0

@johnsample:为此更新。 – PinnyM 2013-04-12 13:55:24