如何在has_many关系中急切加载最新的对象?

时间:2011-01-20 05:43:15

标签: sql ruby-on-rails ruby-on-rails-3 arel

我有一个rails 3应用程序,其中包含类别和帖子等模型。

分类

has_many:帖子

发布

belongs_to:category

我希望能够显示一个类别列表,其中列出了最近发布的帖子,而没有循环访问并点击每个类别的数据库,并且每个类别只撤回一个帖子。

我想做同样的问题 - SQL join: selecting the last records in a one-to-many relationship - 但希望使用Active Record。

这是一件蠢事吗?我是否应该通过急切加载来撤回所有类别的帖子?我很关心性能,这就是我开始研究它的原因。

1 个答案:

答案 0 :(得分:3)

如果不自行构建查询,我不确定这是否可行。这样做的问题是当你开始有条件地或试图限制结果时,rails处理急切加载的方式并不是那么好。你可以通过创建另一个关联来做几乎做你想做的事情:

class Category < ActiveRecord::Base
  has_one :last_post, :class_name => "Post", :foreign_key => "category_id", :order => "created_at desc"
end

然后您可以正常使用包含:

Category.includes(:last_post).all

但是,问题在于,由于这会生成sql,它仍然会从类别中选择所有帖子,即使您调用category.last_post时它只返回最后一个帖子。它会生成与此类似的SQL:

SELECT `categories`.* FROM `categories`
SELECT `posts`.* FROM `posts` WHERE (`posts`.category_id IN (1,2)) ORDER BY created_at desc