2010-08-20 2 views
7

Я использую Memcached как хранилища объектов с моим приложением Rails где хранятся результаты поиска, которые являются объектами пользователя в MemcachedMemcached как хранилище объектов в 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, и в этом случае, я думаю, вам придется прибегнуть к 1-му решению в этой теме. –

+0

Это отлично поработало для меня, спасибо! –

+0

@KonstantinGredeskoul Просто пропустите preload_models часть –

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-у» путь. Но это должно подражать этому!

Приветствия,

Chris

+0

работает для меня. хорошее решение – ifightcrime

Смежные вопросы