Capita talvolta di dover implementare la creazione/modifica di un model suddivisa su più di una form.
Un caso abbastanza classico può essere una form di registrazione suddivisa in due step oppure la realizzazione di un wizard guidato composto da diverse pagine.
Questa situazione ci pone davanti ad un problema: come e quando effettuare la validazione dei dati?
La prima idea che può venire in mente è di demandare semplicemente tutte le validazioni all’ultima pagina quando si va realmente a creare/aggiornare il model. Ma questa è anche la soluzione meno elegante, sia dal punto di vista del codice che da quello dell’usabilità.
Cosa fare allora?
Vi presento una tecnica che ho adottato in situazioni simili per realizzare la “validazione parziale di un model”.
L’idea è quella di implementare un metodo che permetta di validare solo gli attributi presenti ad ogni step.
Iniziamo definendo, all’interno del nostro model, un metodo per la validazione di un singolo attributo:
1 2 3 4 5 6 7 |
def self.valid_attribute?(attrib, value) |
Questo metodo fa uso di un mock per simulare la validazione del model e verifica se nella hash degli errori di validazione sia presente anche l’attributo (attrib) che ci interessa.
Se cosi non fosse il metodo si limita a ritornare true, senza considerare gli altri errori, facendo cosi superare la validazione (parziale!) al model.
Ma vediamone un esempio di utilizzo.
Supponiamo di voler realizzare una form di registrazione in due passaggi, dove nel primo step vengono richiesti utente e password e nel secondo i dati anagrafici.
Aggiungiamo il vincolo che la registrazione sia considerata completa solo se vengono forniti tutti i dati.
In questa situazione ci è comodo utilizzare la validazione parziale.
Definiamo il model User come segue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class User < ActiveRecord::Base |
Supponiamo ora di avere una prima form che richiede all’utente di digitare utente, password ed email ed una seconda form che richiede i dati anagrafici.
Le due form eseguono il post sui metodi step1 e step2 del controller UserController.
Nello step1 possiamo ora utilizzare il metodo valid_attribute? definito in precedenza per validare solo gli attributi che effetivamente ci interessano.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
class UserController < ApplicationController |
Nello step2 eseguiamo invece il metodo save che fa la validazione “classica” di Rails, poichè è l’ultimo step della nostra registrazione ed è qui che creiamo realmente l’utente.
Con la tecnica mostrata si possono aggiungere quanti step si vuole, con l’accortezza di non salvare mai il model fino a che non si è arrivati all’ultimo step.
Nel caso si debbano realizzare più wizard può essere comodo spostare il metodo validate_attribute? in un module da utilizzare come mixin per tutte le classi che ne hanno bisogno.
Naturalmente questa è solo una possibile soluzione al problema della validazione parziale.
Vi siete mai trovati ad affrontare il problema della validazione parziale?
E se si, come lo avete risolto?