Tipicamente un'applicazione riceve informazioni tramite la compilazione di form da parte degli utenti oppure grazie alla trasmissione di dati tramite Web Service. In ogni caso è utile poter verificare che questi dati siano stati immessi in modo corretto prima di salvarli sul database, per evitare malfunzionamenti e problemi di sicurezza.
Per questo dobbiamo stabilire delle regole. Individuiamo ad esempio alcune regole per controllare i dati relativi ai nostri bookmark:
- Ogni bookmark inserito deve avere un URL e un titolo
- Ogni bookmark ha un URL differente
- L'URL e il titolo di ogni bookmark non devono essere più lungi di 256 caratteri
La verifica della correttezza dei dati è chiamata validazione e la validazione si svolge all'interno del modello, dove descriviamo il comportamento di una risorsa e gestiamo l'interazione con la tabella abbinata.
Individuiamo il file che descrive il modello della risorsa Bookmark, app/models/bookmarks.rb
. Secondo la convenzione delle applicazioni Rails, ogni modello ha un corrispondente file nella cartella app/models
che ha lo stesso nome del modello che descrive. Apriamo il file con un editor di testi e modifichiamolo come segue:
class Bookmark < ActiveRecord::Base validates_presence_of :url, :title, :message => "Ogni bookmark inserito deve avere un URL e un titolo" validates_uniqueness_of :url, :message => "Due bookmark devono avere URL differenti" validates_length_of :url, :title, :maximum => 256, :message => "L'URL e il titolo di non devono essere più lungi di 255 caratteri" end
Le validazioni si esprimono nel formato:
<tipo di validazione><attributi a cui applicare la validazione> :message => <messaggio di errore>
Un record è considerato valido e salvato sul database se verifica tutte le regole specificate; se anche solo una regola non viene rispettata, il salvataggio non viene effettuato.
Salviamo il file appena modificato, avviamo il Web server e puntiamo il browser alla pagina per la creazione di un nuovo bookmark (http://0.0.0.0:3000/bookmarks/new
).
Proviamo a inserire un bookmark con un URL già presente in archivio e titolo e descrizione a piacere.
Abbiamo stabilito che questo inserimento non è valido. Premendo il pulsate Create
l'applicazione si rifiuterà di salvare il bookmark, evidenziando in rosso il campo URL
, che non ha superato la validazione e riportando il messaggio di errore che abbiamo indicato nel modello.
Il form, generato tramite scaffold
, riporta l'errore di validazione riscontrato durante l'inserimento dei dati ed evidenzia automaticamente il campo interessato dall'errore. Questo capita anche quando sono presenti più errori. Se ad esempio proviamo a salvare un bookmark lasciando in bianco i campi url
e title
, entrambi obbligatori, il sistema evidenzerà in rosso entrambe le violazioni.
Come abbiamo detto la validazione avviene a livello di modello e non sulla pagina del form. Questo perché sono sempre separati i comportamenti del sistema dallo strato di presentazione. Non importa se abbiamo inserito i dati da form HTML o da Web Service o da console, i controlli vengono effettuati in ogni caso nello stesso modo.
Facciamo un esempio inserendo un nuovo bookmark tramite console Rails. Fermiamo il Web server(CTRL+C
) e avviamo la console:
$ ruby script/console Loading development environment (Rails 2.1.0) >>
Creiamo un nuovo bookmark con URL, titolo e descrizione non compilati:
>> bookmark = Bookmark.new => #<Bookmark id: nil, url: nil, title: nil, description: nil, created_at: nil, updated_at: nil>
Siamo nella stessa situazione del form vuoto. Indichiamo URL e titolo del nostro nuovo bookmark inserendo un URL già utilizzato:
>> bookmark.url = "http://ruby.html.it" => "http://ruby.html.it" >> bookmark.title = "Tutto sul mondo Ruby" => "Tutto sul mondo Ruby"
Proviamo ora a salvare il bookmark:
>> bookmark.save
=> false
Il valore false
restituito indica che il salvataggio non è andato a buon fine. Vediamo gli errori che impediscono il salvataggio:
>> bookmark.errors
=> #<ActiveRecord::Errors:0x249f0b4 @errors={"url"=>["Due bookmark devono avere URL differenti"]}, @base=#<Bookmark id: nil, url: "http://ruby.html.it", title: "Tutto sul mondo Ruby", description: nil, created_at: nil, updated_at: nil>>
>>
@errors
indica il campo che ha generato l'errore e il relativo messaggio (lo stesso che abbiamo visto comparire in testa al form).