2011-10-05 6 views
9

Estoy implementando algo de almacenamiento en caché mediante el ingenioso Rails.cache.fetch. Sin embargo, en un caso particular, a veces me encuentro con una excepción:Excepción de Rails.cache.fetch: TypeError (<ModelName> no se puede hacer referencia)

TypeError in EmloController#index 

Emlo can't be referred to 

app/controllers/emlo_controller.rb:320:in `get_employees' 
app/controllers/emlo_controller.rb:356:in `prepare_json_response' 
app/controllers/emlo_controller.rb:23:in `block (2 levels) in index' 
app/controllers/emlo_controller.rb:15:in `index' 

Parece que el Fetch siempre explotar (con lo anterior) en el primer intento, y luego trabajan muy bien siempre y cuando el fetch es dentro de la expiración . Sé que me estoy perdiendo algo, por lo que un par de ojos frescos sería agradable.

Aquí está el método que invoca la memoria caché tomará:

def get_employees 

    # This is for a AJAX refresh loop, so a 5-second cache actually helps quite a bit 
    Rails.cache.fetch('emlo_all', :expires_in => 5.seconds, :race_condition_ttl => 1) do 

    conditions = (params[:id]) ? {:user_id => params[:id]} : nil 

    selections = [ 
     'employee_locations.id AS emlo_id', 
     'employee_locations.status_id', 
     'employee_locations.notes', 
     'employee_locations.until', 
     'employee_locations.updated_at', 
     'employee_locations.user_id', 
     'location_states.id AS state_id', 
     'location_states.title AS status_string', 
     'location_states.font_color', 
     'location_states.bg_color', 
     'users.displayname', 
     'users.email', 
     'users.mobile', 
     'users.department', 
     'users.extension', 
     'users.guid', 
     'users.dn' 
    ].join(', ') 

    Emlo.all(
     :select => selections, 
     :joins => 'LEFT JOIN users ON employee_locations.user_id=users.id LEFT JOIN location_states ON employee_locations.status_id=location_states.id', 
     :conditions => conditions, 
     :order => 'users.displayname ASC' 
    ) 
    end 
end 
+0

Bueno, por ahora, he decidido simplemente realizar una 'caches_action' sobre la acción que se pide en última instancia, este método . Parece que funciona bien por ahora, pero todavía estoy interesado en aprender lo que otra persona podría decir sobre la excepción que experimenté. –

+0

Acabo de toparme con esto de nuevo, solo que esta vez con 'Rails.cache.write()' y '.read()': "' TypeError ( no se puede hacer referencia) '" –

+0

Parece que necesitas forzar la clase Emlo que se cargará o los rieles no saben cómo deserializar lo que está en Memcache. –

Respuesta

12

Este problema surge en el modo de desarrollo, cuando config.action_controller.perform_caching = true Y config.cache_classes = false - parece objetos ActiveRecord no se pueden almacenar con Rails.cache.

Pero si necesita habilitar config.action_controller.perform_caching en modo de desarrollo para probar el almacenamiento en caché, también debe habilitar config.cache_classes. Sin embargo, esto sería temporal, porque entonces tendría que reiniciar el servidor de desarrollo después de cambiar las clases o los archivos en la canalización de activos.

Con el almacenamiento en caché desactivado, utilizaría Rails.cache.write(some_name, some_value) if Rails.env.production? para evitar que el almacenamiento en caché explote durante el desarrollo. Rails.cache.read() no parece verse afectado.

-1

Dependiendo de la estructura de su aplicación, es posible que obtenga un error en el desarrollo de la siguiente manera: TypeError (Usuario no se puede hacer referencia) Este error es causado por alguna locura almacenamiento en caché-recarga: El middleware implantado por alguna joya está en caché Pero en desarrollo, tus clases usualmente no lo son. Por lo tanto, algunas clases pueden no estar disponibles bajo ciertas circunstancias, p. si está utilizando filtros anteriores para la autenticación de usuario proporcionada por algún motor. Debería poder deshacerse del error anterior activando el almacenamiento en caché de clase. Probarlo (y reiniciar el servidor después):

development.rb

config.cache_classes = true

Si el error se ha ido, estás de suerte. Pero dado que no es posible almacenar en caché las clases en desarrollo, apague el almacenamiento en caché de clase nuevamente y solicite explícitamente la clase que no se pudo derivar. IE:

parte superior de development.rb

requieren 'app/modelos/usuario

Cuestiones relacionadas