2010-08-20 82 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