Un difetto rilevante del nostro sistema di autenticazione è che l'utente riceve un feedback molto poco evidente riguardo il fatto che il login è andato a buon fine, ovvero il piccolo link "logout" in cima alla pagina. L'ideale sarebbe di mettere un testo ben evidente "Il login è stato eseguito" subito dopo che l'utente è stato reindirizzato all'indice, ma se questo rimanesse lì per tutta la durata della navigazione risulterebbe inutile e fastidioso. L'uso di session
è quindi, sebbene possibile, inadatto a questo problema specifico.
Il problema in realtà è un caso particolare di una situazione molto più generale, ovvero la necessità in un'applicazione web di mantenere alcuni dati tra una pagina e l'altra, senza però renderli disponibili per l'intera durata della visita. Dovrebbe essere evidente quanto ciò sia utile, ad esempio, quando sia necessario mostrare dei messaggi d'errore ad un utente, messaggi che sono concettualmente legati ad una singola pagina e non all'intera applicazione. Fortunatamente, ancora una volta, questo problema è stato già affrontato in ambiti di produzione dagli autori di Rails e quindi è stato progettato un meccanismo che permette di affrontarlo con una semplicità estrema: l'oggetto chiamato flash
.
Un flash
, è ancora una volta un'insieme di valori accessibili per chiave, che vengono impostati da un'azione e sono accessibili solamente in quella seguente. Si può raggiungere questo oggetto tramite il metodo omonimo, esattamente come per session
e request
. L'utilizzo è davvero molto semplice, nel nostro caso sarà possibile aggiungere una sola linea al metodo logged
in UserController
:
def logged
session['login']= @author.name
flash['notice'] = "login effettuato per "+@author.name
redirect_to(:controller=>"home")
end
ed ovviamente mostrare questo messaggio nella vista index.rhtml
del controller Home
:
<%= flash['notice'] %>
Se provate ad eseguire il login adesso noterete che la home page mostra questo messaggio la prima volta che essa viene caricata, ma che le volte seguenti esso non appare più proprio come desideriamo.
Sebbene quanto appena visto sia già molto utile, l'oggetto flash offre alcune funzionalità aggiuntive, di cui però non abbiamo bisogno nella nostra semplice applicazione. In particolare, esiste il modo di far durare il flash più a lungo o ancora meno. Se nell'azione azione_di_mezzo
vogliamo mantenere un'informazione ottenuta da azione_precedente
e renderla accessibile anche ad azione_seguente
dovremo usare il metodo flash.keep(messaggio)
. Questo ha senso, ad esempio, in un processo di registrazione articolato in più pagine, ma ovviamente non deve essere usato come un sostituto di session
.
Il metodo per rendere un flash ancora più labile è invece flash.now[messaggio]
, che fa sì che le informazioni messe nel flash siano accessibili solo in una determinata azione, e non nella seguente, come se stessimo usando delle normali variabili d'istanza. L'utilità di questo metodo è decisamente ridotta rispetto agli altri, ma ha una sua ragione se pensiamo di utilizzare il flash in un template: un controller può verificare se un'azione ha impostato un messaggio nella chiave "notifica", ed in caso contrario provvedere a mettercene uno generico, senza che la vista debba comportarsi in modo differente.