2010-08-20 4 views
7

ich mit meiner Rails-Anwendung Memcached als Objektspeicher bin mit dem ich die Suchergebnisse speichern, die Benutzerobjekte in Memcachedals Objektspeicher in Rails Memcached

Nun, wenn ich die Daten holen heraus, dass ich die Memcached undefinierte Klasse erhalten/Modul Fehler. Ich fand eine Lösung für dieses Problem in diesem Blog

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

before_filter :preload_models 
    def preload_models 
    Model1 
    Model2 
    end 

, die die Modelle vor der Hand Vorladen empfiehlt. Ich würde gerne wissen, ob es eine elegantere Lösung für dieses Problem gibt und ob es irgendwelche Nachteile bei der Verwendung der Vorspanntechnik gibt.

Vielen Dank im Voraus

Antwort

8

hatte ich dieses Problem so gut und ich denke, dass ich mit einer schönen Lösung kam.

Sie können die Fetch-Methode überschreiben und den Fehler retten und die richtigen Konstanten laden.

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

Diese Lösung ist groß, aber es ist zu aktiven Datensatz Modelle begrenzt. Manchmal werden Sie Nicht-AR-Klassen cachen, in diesem Fall müssen Sie auf die erste Lösung in diesem Thread zurückgreifen. –

+0

Das hat super für mich funktioniert, danke! –

+0

@KonstantinGredeskoul Einfach überspringen die preload_models Teil –

5

Ran über diese heute, geschafft, mit einer knapperen Lösung zu kommen, die für alle Klassen funktionieren sollte.

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 

nicht sicher, warum [MemCacheStore] ist nicht mit ist [MemCacheStore.const_missing] Methode aufgerufen und alles in der normalen „Rails-y“ so genannt zu werden. Aber das sollte das nachahmen!

Cheers,

Chris

+0

funktioniert für mich. nette Lösung – ifightcrime