2012-07-24 68 views
5

我有一个父/子关系在我的应用程序Rails的活动记录选择父母和孩子作为一个结果

class Polling 
has_many :alerts, :dependent => :destroy 

class Alert 
belongs_to :polling 

在对通知我的索引页,我需要出示分别来自父母的一些数据,这结果在两个查询

Alert Load (6.1ms) SELECT * FROM (SELECT * FROM "ALERTS" INNER JOIN "POLLINGS" ON "POLLINGS"."ID" = "ALERTS"."POLLING_ID" ORDER BY "ALERTS"."ID" DESC) WHERE ROWNUM <= 1 
Polling Load (1.8ms) SELECT "POLLINGS".* FROM "POLLINGS" WHERE "POLLINGS"."ID" = 10113 AND ROWNUM <= 1 

显然,这使得网页加载时间相当可怕的,因为它必须通过每一个循环,拉动父对象也是如此。

我已经尝试了一些事情,比如

> Alert.joins(:polling).where(...) 
> Alert.includes(:polling).where(...) 
> Alert.joins(:polling).select('*').where(...) 

而每一次我得到两个不同的查询,当我访问我的索引页。每个警报一个,然后另一个获取其父数据。我如何在一行上做到这一点,以便当我拉动警报时,我也可以获得他们的关联父数据?似乎没有办法从另一端去理解它,因为如果我做了一个Pollings.where(...)它不会把孩子们当作一个群体。

+1

你绝对在包含方法的正确轨道上。另一个角度是尝试Polling.includes(:alerts).where(...)。你能发布你的视图代码吗? – steakchaser 2012-07-24 19:41:22

+0

事情是我们必须从孩子那边去,而不是父方。 – Oranges13 2012-07-25 17:41:26

+0

你不想预加载吗? http://apidock.com/rails/ActiveRecord/AssociationPreload/ClassMethods/preload_associations – toxaq 2012-09-18 04:48:15

回答

2

如果要详细注明SQL,你总是可以尝试find方法传:包括:联接,:其中等includesjoins做同样的事情向下行,当您试图访问数据,但ActiveRecord的行为是不同的。例如,按照3种方式设置对象数组,但它们是不同的。

[1]

alerts = Alert.joins(:polling) 

[2]

alerts = Alert.includes(:polling) 

[3]

alerts = Alert.find(:all, :includes => :polling, :joins => :polling) 

当你

alerts.each do |alert| 
    alert.pollings.each do |polling| 
    p polling 
    end 
end 

您可以看到activerecord如何尝试从数据库或缓存中获取数据。我相信[3]的方式在其他人抛出多个查询时只抛出一个查询。

+0

我发现,即使我使用连接执行Alert.find,但如果使用alert.pollings,它仍然会从数据库中单独退回,所以这就是导致它仍然执行额外查询的原因。我最终还是使用了.select(),并且只是在执行alert.polling_field。奇怪的,但它的作品。 – Oranges13 2012-08-06 16:32:55