如果用戶有10個帖子,這在技術上會做數據庫調用10次?
沒有。
myUser = User.find 123
myUser.posts.each do |post|
puts post.title
end
此處的代碼將運行2個查詢。第一個將通過它的id找到一個用戶,返回一行。第二個將運行一個查詢,詢問具有與myUser
匹配的用戶標識的所有帖子。然後each
將使用該結果迭代。
如果你看在日誌中的發展模式下,它會告訴你它的運行查詢,你應該會看到一個查詢返回所有那些帖子。
Rails使用關聯代理對象來保存您的查詢,當您需要記錄時執行查詢,然後緩存結果。這是一個非常有用的代碼,大部分它爲你處理這樣的事情。
這是Rails的一個特性,不是紅寶石。
在ruby級別,each
只是作用於集合。
def get_letters
puts 'executing "query"'
sleep(3)
["a","b","c"]
end
get_letters.each do |item|
puts item
end
這應該打印出來。
executing "query"
a
b
c
的get_letters
方法執行,它會返回一個數組,一個數組已滿的數據就是我們所說的each
方法,這樣我們就可以處理每個項目。獲取集合並遍歷它是2個完全獨立的步驟。
從你的引擎收錄:
# will this run forever?
myArr = ["a","b","c"]
myArr.each do |item|
myArr.push("x")
end
呀會,但不是因爲陣列被過度過「牽強」。
這相當於像這樣的javascript,這更好地說明了這一點。
myArr = ["a","b","c"];
for (var i = 0; i < myArr.length; i++) {
myArr.push('x');
}
原來的陣列,在循環檢查的每個迭代,看看它是否沒有完成。但是因爲陣列每次獲得一個項目的時間會增加一個,所以i < myArr.length
將始終爲true
,因爲它們在每次迭代時都會增加1。出於同樣的原因,您的紅寶石與您的each
循環相同。
它永遠運行,不是因爲你不停地運行一些代碼來重新生成數組。它永遠運行,因爲你是人爲地改變結果數組。
謝謝,但問題。在我的粘貼箱作爲最後一個例子,循環永遠運行......我不明白爲什麼會這樣,如果結果會被「緩存」後,Ruby會修改緩存嗎?如果我在.each帖子循環中添加帖子會發生什麼? – K2xL
@ K2xL請參閱我的編輯,它在基本ruby(非rails)圖層上解釋了更多內容。但是,你的循環,正如張貼,絕對不_永遠不會「永遠運行」。 3秒後,完成。 –
看到我的編輯(我無意中發佈了錯誤的pastebin url) – K2xL