2010-04-14 57 views
0

我正在尋找有關按需加載關聯的Ruby優化的幫助。在Rails中包含關聯優化

這是簡化的例子。我有3個型號:Post,CommentUser。參考文獻是:Post有許多意見和Comment有參考User(:作者)。現在,當我轉到帖子頁面時,我希望看到帖子正文+所有評論(以及他們各自的作者姓名)。這需要以下2個查詢:

select * from Post -- to get post data (1 row) 
select * from Comment inner join User -- to get comment + usernames (N rows) 

在代碼中,我有:

Post.find(params[:id], :include => { :comments => [:author] } 

但預期它不工作:正如我在後臺看到的,仍然是N + 1命中(其中一些被緩存)。我該如何優化?

UPD 經過一番調查後,它看起來像代碼是正確的,但如預期的情況下,我有一個名爲belongs_to的在評論模型這是行不通的。一旦我從:作者更改爲:用戶,它按預期工作。

回答

1

如果你很高興與2/3的查詢,你可以嘗試:

@post = Post.find params[:id] 
@comments = Comments.find_by_post_id(params[:id], :include => [:author]) 

@comments = @post.comments(:include => [:author]) 

編輯:您是否嘗試過用:

Post.find(PARAMS [ :id],:include => {:comments =>:author}

+0

我做得對由最後一個變種,仍然看到的評論#,它單獨加載的作者(命中數據庫不止一次, )。 – Vitaly 2010-04-14 19:06:32

+0

http://guides.rubyonrails.org/active_record_querying.html#nested-associations-hash,它看起來像你可以巢包括 – Corey 2010-04-14 19:09:27

+0

@Corey - 是的,我正在關注這篇文章,你可以看到我的問題,但那樣做沒有按預期工作。 – Vitaly 2010-04-14 19:10:56

1

在我的項目中我有一個類似的關係,你的Post,CommentUser模型。我只看到三個實際的sql查詢。

Post.find(1, :include => { :comments => [:author] }) 

從調試日誌中就顯示了這三種查詢

SELECT * FROM `posts` WHERE (`posts`.`id` = 1) 
SELECT `comments`.* FROM `comments` WHERE (`comments`.`post_id` = 1) 
SELECT * FROM `authors` WHERE (`authors`.`id` IN (4,8,15,16,23,42)) 
+0

我更新後,它根據我在belongs_to中的內容改變了它拉取用戶(作者)的方式。 – Vitaly 2010-04-14 19:25:36

+0

您是否研究過如何通過創建日期desc來訂購註釋? – Vitaly 2010-04-15 19:30:26

+0

所以你的意思是這樣嗎?:Post.find(1,:include => {:comments =>:author},:order =>'comments.created_at desc') – Corey 2010-04-15 19:52:33