2012-11-15 99 views
9

我想優化我的整個我的網站查詢。深入嵌套加入主動記錄

我有3種型號,照片,人,出場

照片的has_many露面,許多人透過現象 出場表只是有一個爲person_id,photo_id

現在,如果我在做搜索「人」,我想急於負載其外觀和照片,我會做這樣的事情:

Person.joins(:appearances => :photo).limit(5) 

現在,我不知道這是否是理想的,但假設我的人都有屬於出場一張照片,這張照片又有外表和其他人。我甚至不知道在香草SQL中是否或如何做到這一點,但我只是好奇,如果這是可能的。

Person.joins(:appearances => :photo => :appearaces => :person).limit(5) 

這句法導致錯誤後,再次,我只是好奇,我處理得到的外觀和我的意見內照片的人,我只是想實驗的加載時間,看看這是否是甚至可能。

回答

11

對於'急切加載',您使用.include; .join用於執行INNER JOIN功能。對於你的情況,你可能會同時使用這兩種方式(加入獲取照片,包含獲得更多人)。我提出這一點是因爲.join本身不會執行預先加載(所以它會在訪問關聯實體後進行查詢)。

如果你想急於負荷嵌套關聯的,可以使用在Ruby on Rails的概述的語法指導在http://guides.rubyonrails.org/active_record_querying.html#eager-loading-multiple-associations

將東西沿着這些路線的工作嗎?

Photo.joins(:appearances => :person).includes(:appearances => :person).limit(5) 

或者您是否需要從該人開始?

Person.joins(:appearances => :photo).includes(:appearances => :photo => :appearaces => :person).limit(5) 

此外,作爲最後的(小)注:你有「:出現」在代碼的最後一行拼寫錯誤(它規定「:appearaces」),這可能會導致問題。

編輯: 一些小的測試後,似乎嵌套包括協會在

a => b => c => b => a 

形式不起作用。但是,下面的表格確實如此:

a => [b => [c => [b => a]]] 

雖然,它不是很漂亮。

含義,使用下面的代碼:

Person.includes(:appearances => [:photo => [:appearances => :person]]).find(38)  

生成的SQL語句:

Person Load (0.3ms) SELECT `persons`.* FROM `persons` WHERE `persons`.`id` = 38 LIMIT 1 
Appearance Load (0.3ms) SELECT `appearances`.* FROM `appearances` WHERE (`appearances`.person_id = 38) 
Photo Load (0.3ms) SELECT `photos`.* FROM `photos` WHERE (`photos`.`id` = 1904) 
Appearance Load (0.3ms) SELECT `appearances`.* FROM `appearances` WHERE (`appearances`.photo_id = 1904) 
Person Load (0.3ms) SELECT `persons`.* FROM `persons` WHERE (`persons`.`id` IN (38,346)) 

預先加載從包括人用編號38

+0

地獄所有照片的額外人是的,你是忍者! – jdkealy

+0

打字錯誤...從記憶打字,不能拼寫顯然。 – jdkealy