你正在尋找的模式被稱爲單例,它是一種緩存不隨時間變化的簡單方法,例如,你會在application_controller.rb中看到類似的東西 - 你的代碼始終調用方法
def current_user(user_id)
@current_user ||= User.find user_id
end
當它發生時,它會檢查實例變量@current_user,如果不是nil則返回它,否則它會執行數據庫查找並將結果賦給它返回的實例變量。
您的問題類似,但更廣泛,因爲它適用於所有實例。
一種解決方案是使用類變量,此處記錄了http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_classes.html#S3 - 上述類似的解決方案適用於此處。
這可能是一個很好的解決方案,但有一些問題。具體來說(假設這是一個Web應用程序)取決於您的配置,您可能會在不同的進程中加載多個Rails實例,而類變量僅適用於其特定實例。流行的Passenger模塊(用於Apache和Nginx)可以配置爲允許類變量可以被其所有實例訪問......如果您只有一臺服務器,這非常有用。
但是,當你有多個服務器時,事情會變得有點棘手。當然,你可以使用一個類變量,並接受你必須爲每個服務器創建一個命中數據庫。除了當變量...變化時,這很好用!您需要一些方法來使所有服務器上的變量無效。取決於它的重要性,這可能會造成各種非常難以追查的錯誤(我學會了艱難的方式:-)。
輸入memcached。這是一個很棒的工具,它是一個通用緩存工具。它非常輕巧,非常非常聰明。特別是,它可以在一組服務器上創建分佈式緩存 - 該值只存儲過一次(從而避免了上述同步問題),並且每個服務器都知道要查找哪個服務器以查找任何給定的緩存密鑰。它甚至可以處理服務器停機和各種其他不愉快情況。
安裝非常簡單,Rails幾乎假設您將使用它來滿足您的各種緩存需求,並且Rails gem只是簡單得像餡餅一樣。
假設還有其他機會來緩存可能不像存儲在類變量中的值那麼簡單的東西,那可能是第一個開始的地方。
謝謝!我們是否將值存儲在類變量中,以便通過請求和操作來訪問它們? – Crashalot 2012-03-15 19:13:45
布拉德利得出了同樣的結論,比我在答案中更快,更實際的方式:-)。不,Rails.cache替代了類變量的方法。 – 2012-03-15 19:15:37
我剛更新了包含me忘記的方法,我忘記了,謝謝tharrison。跨實例的類方法很少是一個好主意,從Rails緩存中讀取幾乎是免費的,因此您可以調用該方法。這裏唯一的問題是如果你有多個服務器,數據可能在不同服務器上有所不同。在這種情況下,肯定會考慮將諸如Memcached之類的東西插入到Rails.cache的後端 – 2012-03-15 19:19:39