ActiveRecord Eager在初始查询后加载

时间:2016-02-16 02:15:12

标签: ruby-on-rails postgresql activerecord

假设我有一个简单的模型关联,其中博客Post上有很多Comments

class Post < ActiveRecord::Base
  has_may :comments
end

如果我想避免“N + 1”查询并预先加载所有关联,我可以这样做 -

Post.includes(:comments).where(title: "foo")

哪个运行两个查询。第一个使用Post条件查找where,第二个查找所有关联的comments

但是如果我已经拥有Post对象怎么办?我可以在初始结果集之后向其添加includes以运行查找所有关联的第二个批量查询吗?

做一个延迟的急切负载似乎是违反直觉的,但我认为一次查找所有关联仍然可以让我不必在我循环时单独查找它们。

e.g。

p = Post.where(title: "foo")

# Will the below work?
p.includes(:comments)

p.comments.each do |comment|
  puts comment.text
end

1 个答案:

答案 0 :(得分:2)

让我们分解您的代码。

posts = Post.where(title: 'foo')

搜索标题为foo的所有帖子。 posts是一个ActiveRecord::Relation对象,您可以链接更多ActiveRecord命令,例如selectlimitincludes等。

这样做posts.includes(:comments)是有效的,应该急于加载评论。不要忘记再次将结果分配给posts(或其他变量)。

posts.comments是不可行的,因为comments是一种适用于Post实例的方法。更改为以下代码将起作用

posts = Post.where(title: 'foo')
posts = posts.includes(:comments)

posts.each do |post|
  post.comments.each do |comment|
    puts comment.text
  end
end