2016-02-16 33 views
1

比方說,我有一個簡單的模型關聯,其中博客Post上有很多CommentsActiveRecord Eager在初始查詢後加載

class Post < ActiveRecord::Base 
    has_may :comments 
end 

如果我想避免「N + 1」的查詢和貪婪加載所有關聯事前,我可以做 -

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

,哪個跑得兩個查詢。第一個使用where條件查找Post,第二個查找所有關聯的comments

但是如果我已經有一個Post對象呢?我可以在初始結果集之後「添加」includes以運行查找所有關聯的第二個批量查詢嗎?

做一個延遲的渴望加載看起來並不直觀,但我認爲一次查找所有關聯仍然可以避免我在循環查看時單獨查找它們。

例如

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

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

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

Post.includes(:comments).where(title:「foo」)這將實際上只運行查詢。 它應該是類似於 select * from文章p內部連接評論c on c.post_id = p.id其中p.title ='foo' – Typpex

回答

2

讓我們來分解你的代碼。

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

,搜索與foo標題的所有帖子。 postsActiveRecord::Relation對象,你可以鏈狀selectlimitincludesActiveRecord命令等

這樣算下來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 
+0

謝謝,這在將多個鏈接在一起時有意義 – user2490003