2010-08-20 7 views
7

J'utilise Memcached comme un magasin d'objets avec mon application Rails où je stocke les résultats de recherche qui sont des objets utilisateur dans memcachedmemcached comme un magasin d'objets dans Rails

Maintenant, quand je vais chercher les données sur je reçois la Memcached Undefined classe/Erreur du module. J'ai trouvé une solution à ce problème dans ce blog

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

before_filter :preload_models 
    def preload_models 
    Model1 
    Model2 
    end 

qui recommande de pré-chargement des modèles avant la main. Je voudrais savoir s'il y a une solution plus élégante à ce problème et y a-t-il des inconvénients dans l'utilisation de la technique de préchargement.

Merci à l'avance

Répondre

8

moi avons eu ce problème aussi bien et je pense que je suis venu avec une belle solution.

Vous pouvez écraser la méthode d'extraction et récupérer l'erreur et charger les bonnes constantes.

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

Cette solution est grande, mais il est limité aux modèles de disques actifs. Parfois, vous mettrez en cache des classes non-AR, auquel cas je pense que vous devrez recourir à la première solution sur ce sujet. –

+0

Cela a fonctionné très bien pour moi, merci! –

+0

@KonstantinGredeskoul Il suffit de passer la partie preload_models –

5

couru à travers aujourd'hui, a réussi à trouver une solution plus laconique qui devrait fonctionner pour toutes les classes.

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 

Je ne sais pas pourquoi [MemCacheStore] est de ne pas avoir est appelé méthode [MemCacheStore.const_missing] et tout ce qui se fait appel à la normale façon « Rails-y ». Mais, cela devrait imiter ça!

Cheers,

Chris

+0

qui fonctionne pour moi. belle solution – ifightcrime

Questions connexes