2013-04-15 107 views
1

我必須在我看來,下面的代碼段:模型方法的觀點

<% if @user.get_products.any? %> 
    <%= f.select('products', @user.get_products.collect { |user| [user.name, user.id]}) %> 

get_products正在做出ActiveRecord查詢數據庫。所以我想知道它是否實際上做了兩個相同的查詢,或者在第二次調用時使用第一個查詢的緩存結果?我試圖在服務器日誌中檢查它 - 但沒有發現任何東西。我也想知道我是否可以以某種方式控制這種行爲,即爲此視圖設置/取消設置緩存。

謝謝!

UPDATE:

我認爲它違反了MVC過,但什麼困惑我的是IDE的警告:「鑑於不應該與控制器共用兩個以上的變量。」

但是,我創建了一個「一個頁面」的網站,所以我需要在同一視圖中有@user,@nearest_users@user_products。所以,我發現了下面的文章:
http://matthewpaulmoore.com/post/5190436725/ruby-on-rails-code-quality-checklist#instances

其中所述

只有一個或兩個實例變量是每個控制器 和視圖之間共享。

實例變量hell - 在控制器和視圖之間共享大量實例變量 - 在Rails中很容易實現。這也是 性能潛在的危險,因爲你可以在不知不覺中最終制造 重複呼叫。相反,您的控制器 應該只管理一個實例變量 - 也許是current_user的第二個實例變量。這樣,所有對關聯的調用都會被加載「on demand」,並且可以在單個地方緩存實例變量。

此方法也適用於片段緩存,因爲在實際加載關聯之前,您可以在視圖中檢查緩存。

例如,而不是你的博客控制器創建兩個@post和@related_posts一個實例變量 ,只是做了一個方法, @post,並給予安置自己的模型related_posts方法,這樣你就可以 剛在你的意見中打電話@ post.related_posts。

+4

這通常被認爲是不好的做法,因爲它違反了MVC和Liskov替換。嘗試使用您的控制器或助手訪問ActiveRecord。也許你應該分配@products,你可能會發現更細粒度測試的問題。 – Tsagadai

+0

如果你看看你的服務器日誌,你應該看到藍色查詢查詢和紫色緩存查詢。大會只是使用'products'而不是'get_products' btw – AJcodez

回答

2

回答你的問題:查詢中的查詢不會被緩存。

更重要的是,ERB模板中的Ruby代碼使用eval執行,效率非常低。

所以我的建議是:避免在視圖中編寫邏輯,這是一種不好的做法。

+0

我從RubyConf China 2012的幻燈片中瞭解到這一點。你可能不會讀中文,但如果你這樣做,這裏是幻燈片:http:// blog。 xdite.net/posts/2012/11/20/rubyconf-china-2012-ten-slow-things-you-dont-know/ –