2011-10-05 12 views
9

Sto implementando un po 'di cache usando l'elegante Rails.cache.fetch. Tuttavia, in un caso particolare, a volte rilevare un'eccezione:Eccezione Rails.cache.fetch: TypeError (<ModelName> non può essere definito)

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' 

Sembra che il fetch sempre esplodere (con il sopra) al primo tentativo, e quindi funzionano bene fintanto che il recuperare è entro la scadenza . So che mi manca qualcosa, quindi un nuovo paio di occhi sarebbe bello.

Ecco il metodo che invoca la cache recuperare:

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

Bene, per ora, ho deciso di solo eseguire un 'caches_action' sull'azione che alla fine chiama questo metodo . Sembra che funzioni per ora, ma sono ancora interessato ad apprendere ciò che qualcun altro potrebbe dover dire sull'eccezione che ho vissuto. –

+0

Ho appena eseguito nuovamente questa operazione, solo questa volta con 'Rails.cache.write()' e '.read()': "' TypeError ( non può essere definito) "" –

+0

Suoni come se fosse necessario forzare la classe Emlo da caricare oppure i binari non sanno come deserializzare ciò che è in memcache. –

risposta

12

Questo problema si pone in modalità di sviluppo, quando config.action_controller.perform_caching = true E config.cache_classes = false - sembra oggetti ActiveRecord non possono essere memorizzati con Rails.cache.

Ma se è necessario abilitare config.action_controller.perform_caching in modalità sviluppo per testare la memorizzazione nella cache, è necessario abilitare anche config.cache_classes. Ciò sarebbe tuttavia temporaneo, poiché in tal caso sarà necessario riavviare il server di sviluppo dopo aver modificato classi o file nella pipeline degli asset.

Con la memorizzazione nella cache disabilitata, vorrei utilizzare Rails.cache.write(some_name, some_value) if Rails.env.production? per evitare che la memorizzazione nella cache possa esplodere durante lo sviluppo. Rails.cache.read() non sembra essere interessato.

-1

A seconda della struttura della vostra applicazione, si potrebbe ottenere un errore in fase di sviluppo come questo: TypeError (L'utente non può essere definito) Questo errore è causato da un po 'di follia caching-ricarico: Il middleware impiantato da qualche gemma è memorizzato nella cache. Ma nello sviluppo, le tue lezioni di solito non lo sono. Pertanto alcune classi potrebbero non essere disponibili in determinate circostanze, ad es. se si utilizza prima dei filtri per l'autenticazione utente fornita da qualche motore. Dovresti essere in grado di eliminare l'errore sopra attivando la cache di classe. Provalo (e riavviare il server in seguito):

development.rb

config.cache_classes = true

Se l'errore è andato, sei fortunato. Ma poiché non è possibile memorizzare nella cache le classi in fase di sviluppo, disattivare di nuovo la cache di classe e richiedere esplicitamente la classe a cui non è possibile fare riferimento. IE:

cima development.rb

richiedono 'app/modelli/utente'

Problemi correlati