2010-08-20 33 views
7

我使用Memcached的與我的Rails應用程序對象存儲在哪裏存儲搜索結果這是在memcached的memcached的在Rails的對象存儲

用戶對象現在,當我取出來的數據我得到的Memcached的未定義類/模塊錯誤。我發現這個問題的解決方案,在這個博客

http://www.philsergi.com/2007/06/rails-memcached-undefinded-classmodule.html

before_filter :preload_models 
    def preload_models 
    Model1 
    Model2 
    end 

其前手建議預加載模型。我想知道是否有更優雅的解決方案來解決這個問題,並且在使用預加載技術方面有什麼缺點。

在此先感謝

回答

8

我也有這個問題,我想我想出了一個很好的解決方案。

您可以覆蓋獲取方法並挽救錯誤並加載正確的常量。

module ActiveSupport 
    module Cache 
    class MemCacheStore 
     # Fetching the entry from memcached 
     # For some reason sometimes the classes are undefined 
     # First rescue: trying to constantize the class and try again. 
     # Second rescue, reload all the models 
     # Else raise the exception 
     def fetch(key, options = {}) 
     retries = 2 
     begin 
      super 
     rescue ArgumentError, NameError => exc   
      if retries == 2 
      if exc.message.match /undefined class\/module (.+)$/ 
       $1.constantize 
      end 
      retries -= 1 
      retry   
      elsif retries == 1 
      retries -= 1 
      preload_models 
      retry 
      else 
      raise exc 
      end 
     end 
     end 

     private 

     # There are errors sometimes like: undefined class module ClassName. 
     # With this method we re-load every model 
     def preload_models  
     #we need to reference the classes here so if coming from cache Marshal.load will find them  
     ActiveRecord::Base.connection.tables.each do |model|  
      begin  
      "#{model.classify}".constantize 
      rescue Exception  
      end  
     end  
     end 
    end 
    end 
end 
+0

這個解決方案是偉大的,但它僅限於活動記錄模式。有時你會緩存非AR類,在這種情況下,我認爲你不得不求助於這個線程的第一個解決方案。 – 2011-08-16 00:47:48

+0

這對我很好,謝謝! – 2012-03-26 21:18:33

+0

@KonstantinGredeskoul只需跳過preload_models部分 – 2012-08-29 23:36:34

5

今天跨過這個,設法提出了一個更簡潔的解決方案,應該適用於所有類。

Rails.cache.instance_eval do 
    def fetch(key, options = {}, rescue_and_require=true) 
    super(key, options) 

    rescue ArgumentError => ex 
    if rescue_and_require && /^undefined class\/module (.+?)$/ =~ ex.message 
     self.class.const_missing($1) 
     fetch(key, options, false) 
    else 
     raise ex 
    end 
    end 
end 

不知道爲什麼[MemCacheStore]是不是有被稱爲[MemCacheStore.const_missing]方法,一切都得到所謂正常「的Rails-Y」的方式。但是,這應該仿效!

乾杯,

克里斯

+0

爲我工作。好的解決方案 – ifightcrime 2012-04-18 15:46:34