Salve ragazzi,
come posso abilitare la cache di alcune view nel controller solo se
l’utene non è loggato?
Mi spiego meglio:
nel mio view_controller ho:
caches_page :index
ho bisogno di qualcosa del genere:
if session[:user_id]
caches_page :index
end
ovviamente scritto così nel controller non funge.
Come faccio?
Grazie mille
Luigi
Luigi M. wrote:
Salve ragazzi,
come posso abilitare la cache di alcune view nel controller solo se
l’utene non è loggato?
Mi spiego meglio:
nel mio view_controller ho:
caches_page :index
ho bisogno di qualcosa del genere:
if session[:user_id]
caches_page :index
end
ovviamente scritto così nel controller non funge.
Come faccio?
Grazie mille
Luigi
Prova con:
caches_page :index, :if => Proc.new {|c| c.request.session[:user_id] }
Innanzitutto scorda caches_page.
Ti spiego, questa macro genera un file html statico nella tua cartella
pubblica, tutte le successive request verranno soddisfatte servendo
staticamente quel file.
Per cui se il primo utente che visita quella route è loggato, è
probabile che quella pagina abbia qualche contenuto che non dovrebbe
essere visibile ad un utente che non lo è. Esempio: il link “logout”.
In questo caso tutte le request successive verranno servite con quello
specifico output. Il che ovviamente non va bene, perché potrebbe
contenere dati sensibili dell’utente.
La soluzione è caches_action
(http://api.rubyonrails.org/classes/ActionController/Caching/Actions.html),
la quale genera ugualmente dell’html, ma ne fa lo storing nella cache di
Rails, anziché nella cartella pubblica. Questo comporta una differenza
sostanziale, perché la request passa sempre attraverso ActionPack,
quindi con i tuoi before_filter puoi decidere se e quando utilizzare il
caching.
Ti consiglio queste letture:
http://www.railsenvy.com/2007/3/20/ruby-on-rails-caching-tutorial-part-2
*
Luca
Ciao Claudio, lo provo stasera dovrebbe fare al caso mio.
Ciao Luca,
grazie mille per l’aiuto.
La macro caches_page so che genera il file html statico e dato che per
l’applicazione in questione solo io modifico il db, ogni volta che ci
entro e lo modifico viene lanciata la cancellazione dei file statici.
Il problema, come hai intuito, è proprio il link al logout che non deve
essere memorizzato nel file statico quando io sono loggato, però
appunto, dato che si tratta della home page, il relativo file statico
viene cancellato ad ogni modifica.
Cmq per alcune view, come la index, può sicuramente essere conveniente,
come dici tu, utilizzare la caches_action.
Per altre view che si distinguono una dall’altra per il percorso in cui
si trovano e non per il nome, non posso utilizzare la caches_action
perché non funzionerebbe da cache.
Grazie mille!!!
Luigi
Ciao ragazzi,
stavo provando la soluzione suggerita da Claudio ma non funge:
caches_page :index, :if => Proc.new {|c| !c.request.session[:user_id] }
…ho aggiunto un punto esclamativo perché a me serve che il cache_pages
venga eseguito solo se NON si è loggati.
Ad ogni modo non funziona neppure senza punto esclamativo e cioè il
caches_page lo fa sia che si è loggati che non!
Suggerimenti?
Grazie mille come sempre
Luigi
Ciao,
Il giorno 04/mag/09, alle ore 12:25, Luca G. ha scritto:
Per cui se il primo utente che visita quella route è loggato, è
probabile che quella pagina abbia qualche contenuto che non dovrebbe
essere visibile ad un utente che non lo è. Esempio: il link “logout”.
In questo caso tutte le request successive verranno servite con quello
specifico output. Il che ovviamente non va bene, perché potrebbe
contenere dati sensibili dell’utente.
come hai giustamente detto, l’output specifico per un utente loggato
potrebbe contenere dati sensibili.
Ad ogni modo, con la dovuta accortezza, è possibile generare file di
cache diversi che riportino come prefisso, ad esempio, l’id
dell’utente loggato.
In questo modo non si rischia di rivelare dati di un utente loggato ad
un’altro.
Il meccanismo si chiama fragment_caching, ed è spiegato nell’episodio
#7 della serie “Scaling Rails” (5:22).
Si applica nella vista:
<% cache("#{current_user.id}_frammento_di_cache") do %>
Contenuto da cachare
<% end -%>
e per farlo scadere:
expire_fragment “#{current_user.id}_frammento_di_cache”
---------problema 1--------
…nessuno mi riesce ad aiutare per far funzionare:
caches_page :index, :if => Proc.new {|c| !c.request.session[:user_id] }
che sarebbe l’ideale per me!?!?!
-------problema 2---------
Mi sono nel frattempo, caricando un pò di aggiornamenti al codice,
accorto di avere un altro problema:
Ho voluto migliorare un pò il sito eliminando pagine dinamiche del tipo
…/?category=Antivirus e redirezionandole a indirizzi del tipo
http://www.software-windows.net/lista/software/antivirus.html
questa pagina come altre, come quelle relative alla paginazione, sono
tutte riferite alla vista “index”.
Il problema che ho sta nel fatto che non posso, nel frattempo che i
vecchi indirizzi vengono sostituti, da Google, con i nuovi, attivare il
caches_page o il caches_action su tale vista che genera, ovviamente,
anche l’index del sito.
Qualche idea?
Grazie
Luigi
…perdonatemi non ho completato il discorso:
dicevo, non posso cachare l’index perché la richiesta del tipo
…/?category=Antivirus viene redirezionata all’indirizzo statico tramite
un redirect_to che sta nel controller, in particolare in:
def index
…
end
quindi se faccio la cache della index il codice non viene eseguito e
nemmeno il redirect!
Come potrei fare a cachare lo stesso la index?
Grazie ancora
Luigi
Infatti io parlavo del page caching, il fragment caching è più fine
grained, e serve proprio a questo. Nel caso riportato da Luigi, l’action
caching dovrebbe essere sufficiente.
Luca
Il giorno 06/mag/09, alle ore 09:39, Luigi M. ha scritto:
caches_page :index, :if => Proc.new {|c| !
c.request.session[:user_id] }
Questa soluzione è documentata, cerchiamo di capire perchè non funziona.
A me funziona benone.
Provalo prima con un semplice booleano:
caches_page :index, :if => Proc.new {|c| true }
e
caches_page :index, :if => Proc.new {|c| false }
se funziona vuol dire che c’è un errore nell’espressione !
c.request.session[:user_id].
Inoltre, di default il caching è disabilitato in development. Attivalo
nel file development.rb:
config.action_controller.perform_caching = true
Ciao,
Fabrizio R.
[email protected]
Nel development è abilitato, il mio problema è infatti che l’espressione
:if non lo disabilita!
Cheidevo infatti se per caso ci fosse qualche errore nella stringa:
c.request.session[:user_id]
Grazie
Luigi
Questo dipende dalla tua implementazione.
Anzichè caches_page :index, :if => Proc.new {|c| true }, prova a
mettere un punto di interruzione:
caches_page :index, :if => Proc.new {|c| debugger }
Rilancia il server con l’opzione -u, cancella eventuali file cachati,
ricarica e dovresti entrare in debug.
Il giorno 06/mag/09, alle ore 22:13, Luigi M. ha scritto:
…mmmhhhh…come si fa ad entrare in debug?..e cioè come si lancia il
server con l’opzione -u.
Io uso, in locale, InstantRails2.0.
Grazie
Luigi
Anche senza usare il debug, fatti stampare un output nel browser per
capire qualcosa in pi?la condizione che non ti funziona.
…perdonatemi, ma non so come si fa neppure quest’altra cosa!
Elimina manualmente il file html dalla directory pubblica.
Mi sto perdendo:
Anche senza usare il debug, fatti stampare un output nel browser per
capire qualcosa in più sulla condizione che non ti funziona.
questo voleva dire fai generare al codice le pagine html?
In modo molto rozzo, una cosa del genere:
def index
raise params.inspect
end
Il raise ferma l’esecuzione e ti stampa l’hash params nel browser
Ovviamente è un esempio.
Il giorno 07/mag/09, alle ore 10:47, Luigi M. ha scritto:
Ok, non so su windows che differenze ci siano, quindi non ti posso
aiutare molto.
Anche senza usare il debug, fatti stampare un output nel browser per
capire qualcosa in più sulla condizione che non ti funziona.
Il giorno 07/mag/09, alle ore 10:07, Luigi M. ha scritto: