In questo articolo vediamo come realizzare un piccola applicazione di livello base con Rails e MySQL. Usiamo come pretesto la gestione del magazzino di un supermercato e mettiamo in piedi le funzionalità di inserimento, modifica, eliminazione ed elenco dei prodotti. Come piattaforma per gli esempi utilizziamo Windows.
Modello Concettuale
Supponiamo di aver effettuato una piccola analisi dei requisiti. Il modello concettuale che nella nostra applicazione sarà costituito di due componenti principali: Magazzino
e Prodotto
.
Stabiliamo che il componente Magazzino non contiene alcun attributo, perché costituisce solo un contenitore di componenti Prodotto
. Proprio per questo motivo è utile conoscerlo e descriverlo a livello concettuale ma non sarà indispensabile crearlo nel nostro database.
Il componente Prodotto, invece, contiene 4 attributi ognuno dei quali avrà determinati requisiti da rispettare:
- Il codice, rappresenta l'identificatore del prodotto. Esso dovrà essere composto da 6 caratteri alfanumerici, non potrà essere nullo e dovrà essere unico per ogni prodotto
- La marca del prodotto, dovrà essere composta da massimo 255 caratteri alfanumerici e non potrà essere nulla
- La descrizione del prodotto, dovrà essere composta da massimo 255 caratteri alfanumerici e non potrà essere nulla
- La quantità, rappresenta il numero di articoli di un certo prodotto presenti in magazzino e quindi è un numero non nullo
Lo scheletro del progetto
Per creare il progetto apriamo il Prompt dei comandi, entriamo nella la directory di lavoro (es: c:rails) e creiamo lo scheletro dell'applicazione scrivendo:
rails magazzino
Riepiloghiamo rapidamente il significato delle cartelle principali:
Cartella | descrizione |
---|---|
config |
continene il file database.yml , da modificare per impostare l'uso di un database diverso da SQLite |
db/migrate |
contiene i file che permettono di generare le tabelle del nostro database |
app/models |
contiene le definizioni della logica sui dati |
app/controllers |
contiene la logica del sistema |
app/views |
contiene l'interfaccia utente dell'applicazione |
public/stylesheets |
contiene i fogli di stile |
Configurare la base di dati
Per creare il nostro db accediamo al server MySQL tramite linea di comando:
mysql -uroot
Dopo aver inserito la password (assente nel nostro caso), creiamo finalmente il nuovo database:
mysql> create database magazzino_development;
Una volta fatto, digitiamo "q" per uscire dal manager del database.
Ora, come abbiamo detto, dobbiamo impostare il sistema perché lavori con MySQL. Per farlo andiamo a modificare il file database.yml
, nella cartella app/config
.
development: adapter: mysql database: magazzino_development host: localhost username: root password:
Scaffolding
Per generare automaticamente i componenti dell'applicazione per gestire i dati utilizziamo il comando:
ruby scriptgenerate scaffold prodotto
Esaminiamo rapidamente i file che vengono creati e che possiamo modificare:
File e cartelle relativi all'interfaccia
Per quanto riguarda le interfacce il comando crea la cartella appviewsprodottos
e vi inserisce i le viste:
file | descrizione |
---|---|
index.html.erb |
pagina iniziale della nostra applicazione |
new.html.erb |
pagina di inserimento di un nuovo prodotto |
show.html.erb |
pagina di visualizzazione dei prodotti |
edit.html.erb |
pagina di modifica di un prodotto |
Inoltre questo comando genera nella cartella publicstylesheets
un foglio di stile predefinito chiamato scaffold.css
.
File e cartelle relative al modello
Per il modello il comando crea la cartella appmodels
e al suo interno inserisce il file prodotto.rb
con in quale gestire ad esempio le convalide sugli inserimenti dell'utente.
File e cartelle relative al database
Per quanto riguarda la persistenza verrà creato il file 001_create_prodottos.rb
nella cartella db/migrate
, necessario per la creazione delle tabelle nel database.
File e cartelle relative al controllo
Per quanto riguarda i controller viene creato il file prodottos_controller.rb
nella cartella app/controllers
contenente la logica dell'applicazione.
Creazione delle tabelle
Il nostro database magazzino_development
sarà composto della sola tabella Prodotto
. Per generare la tabella effettuiamo una "migrazione" che ne permette la generazione automatica.
Le informazioni necessarie all'automatismo si trovano nella cartella db/migrate
, chiamato 001_create_prodottos.rb
. Questo file contiene una classe con due metodi:
metodo | descrizione |
---|---|
self.up |
istanzia la tabella nel database |
self.down |
cancella la tabella creata |
Modificiamo il metodo self.up
aggiungendo la definizione delle colonne della tabella prodottos
.
Sintassi per dichiarare le colonne
<tabella>.column:<nomeColonna>, <tipo>, <altri parametri>
Quanto alla nostra applicazione dovremmo specificare gli attributi del Prodotto indicati nel modello concettuale. Il metodo, dopo le nostre modifiche diventa:
def self.up create_table :prodottos do |t| t.column :created_at, :datetime t.column :codice, :string, :null => false t.column :marca, :string, :null => false t.column :descrizione, :string, :null => false t.column :quantita, :integer, :null => false, :default => 0 end end
Oltre gli attributi specificati troviamo la definizione del campo created_at
che serve per tenere traccia della data di creazione dell'entry.
Inoltre, nelle dichiarazioni, affianco al nome e al tipo, abbiamo definito le proprietà:
- :null che può assumere valori
true
(l'attributo può assumere valori nulli) ofalse
(l'attributo non può assumere valori nulli); - :default che inizializza (es.
:default =>0
) il valore di un campo
Fatte tutte le dichiarazioni, generiamo la tabella nel database tornando alla linea di comando e, nella cartella dell'applicazione, digitiamo:
rake db:migrate
che traduce il metodo in codice SQL.
Convalidare i dati
Per convalidare i dati inseriti dall'utente, bisogna stabilire requisiti di validità su ogni attributo generato. Le tipologie di errore che si possono riscontrare sono:
Metodo | Descrizione |
---|---|
validates_presence_of |
verifica che non ci siano valori nulli |
validates_lenght_of |
verifica che non sia superata la lunghezza prestabilita |
validates_numericality_of |
verifica l'inserimento di soli valori numerici |
validates_uniqueness_of |
verifica l'unicità dei valori immessi |
Ad ogni verifica possiamo associare un messaggio di errore utilizzando la sitassi :message =>
.
La classe che si occupea della convalida è definita nel file prodotto.rb
, della directory app/models
.
Gli attributi rispettano i requisiti del modello concettuale e per ogni attributo applichiamo gli opportuni criteri di validazione
Inserimento di un prodotto tramite console
Per testare l'applicazione prima di mettere mano all'interfaccia, possiamo interagire con la nostra applicazione tramite la console di Ruby.
Avviamo la console dalla riga di comando: nella cartella dell'applicazione digitiamo:
ruby scriptconsole
Per creare un nuovo prodotto dobbiamo eseguiamo il comando:
>> prodotto = Prodotto.new()
La sintassi per inserire un oggetto nel database è:
<riferimentoOggetto>.save
Quindi, nel nostro caso scriveremo prodotto.save
. Se la console ci restituisce il valore >> false
siamo in presenza di errori nell'inserimento. L'oggetto ha una lista di errori correlata, che può essere visualizzata tramite la sintassi:
<riferimentoOggetto>.errors
Per modificare i singoli attributi dell'oggetto la sintassi è:
<riferimento>.<attributo> = <valore>
Quindi nel nostro caso modifichiamo il nostro oggetto come in figura.
Nella seconda parte dell'articolo ci occuperemo dell'interfaccia e dell'aspetto grafico dell'applicazione.
Modifiche all'interfaccia
Arrivati a questo punto la nostra applicazione prende forma. Possiamo verificarlo avviando il server:
ruby scriptserver
e puntando il browser all'indirizzo http:localhost:3000prodottos
. Otteniamo la pagina pricipale della gestione dei prodotti.
La pagina principale
Da qui possiamo effettuare le operazioni di visualizzazione, modifica, eliminazione e creazione di un prodotto, cliccando sui relativi link. I tre link Show
, Edit
e Destroy
, in questo caso, sono riferiti all'unico prodotto precedentemente inserito nel database. Per ora non appaiono gli altri dati del prodotto perchè la pagina è ancora scarna. Vediamo come rendere operative e complete le pagine di interfaccia.
Il file che rappresenta la pagina appena vista è appviewsprodottosindex.html.erb
. Dovrebbe contenere la lista dei prodotti presenti nel database e le classiche operazioni CRUD.
Perché funzioni a dovere dobbiamo modificarlo un po'. Iniziamo aggiungendo una tabella con le intestazioni per le colonne e un ciclo che recuperi i prodotti dal database e li visualizzi nelle righe.
<h1>Lista dei prodotti</h1> <table> <tr><th>Data</th><th>Codice</th><th>Marca</th><th>Descrizione</th><th>Quantità</th></tr> <% for prodotto in @prodottos %> <tr> <% for column in Prodotto.content_columns %> <td><%=h prodotto.send(column.name) %></td> <% end %> <td><%= link_to 'Visualizza', prodotto %></td> <td><%= link_to 'Modifica', edit_prodotto_path(prodotto) %></td> <td><%= link_to 'Elimina', prodotto, :confirm => 'Sei sicuro di volere eliminare il prodotto?', :method => :delete %></td> </tr> <% end %> </table>
Già che c'eravamo, abbiamo riscritto in italiano il titolo (<h1>
)e il testo dei link delle operazioni.
Ora pagina principale mostra gli elementi presenti nel database ed è in italiano.
Inserire un nuovo prodotto
La vista che rappresenta la pagina di inserimento dei prodotti è appviewsprodottosnew.html.erb
. È stata generata automaticamente dal comando scaffold
e contiene inizialmente un form e il un bottone Create
per il submit. L'azione del form punta all'inserimento dell'elemento nel database.
Anche in questo caso il più è fatto, dobbiamo solo quasi inserire gli elementi necessari all'inserimento dei dati. La pagina dovrà quindi contenere 4 input di tipo text
che per il codice, la marca, la descrizione e la quantità del prodotto. Inoltre, come nella pagina principale, possiamo tradurre le scritte in italiano.
<% form_for(@prodotto) do |f| %> <p><b>Codice</b><br /> <input class = "text" name="prodotto[codice]" size="30" type="text" value="" /> </p> <p><b>Marca</b><br /> <input class = "text" name="prodotto[marca]" size="30" type="text" value="" /> </p> <p><b>Descrizione</b><br /> <input class = "text" name="prodotto[descrizione]" size="30" type="text" value="" /> </p> <p><b>Quantità</b><br /> <input class = "text" name="prodotto[quantita]" size="30" type="text" value="" /> </p> <%= f.submit "Crea il prodotto" %> <% end %>
Verifichiamo le modifiche sul browser. Dalla pagina principale cliccchimo sul link "Inserisci un nuovo prodotto".
Creando gli input abbiamo reso la pagina operativa al cento per cento. Se inseriamo correttamente i dati, generaimo un nuovo record nella tabella prodotto, in caso contrario, provochiamo la visualizzazione di un messaggio di errore prodotto dall'istruzione:
<%= error_messages_for :prodotto %>
Visualizzare un prodotto
La vista che realizza la visualizzazione dei dettagli di un prodotto è appviewsprodottosshow.html.erb
. La modifica qui consiste nell'importare il valore del prodotto (<%hidden_field 'prodotto','id'%>
) e visualizzare i suoi attributi sullo schermo (es: @prodotto.codice
).
<%= hidden_field 'prodotto','id'%> <p><label for="prodotto_codice">Codice:</label> <%= @prodotto.codice %></p> <p><label for="prodotto_marca">Marca:</label> <%= @prodotto.marca %></p> <p><label for="prodotto_descrizione">Marca:</label> <%= @prodotto.descrizione %></p> <p><label for="prodotto_quantita">Quantità:</label> <%= @prodotto.quantita %></p>
La pagina "show" viene inclusa o chiamata ogni qual volta si effettua un inserimento, una modifica o quando la richiediamo esplicitamente.
In alto appare un messaggio in inglese che ci informa sull'esito dell'azione effettuata ("Prodotto was successfully created"). Questo tipo di messaggio è chiamato flash notice e per modificarlo bisogna accedere al file prodottos_controller.rb
nella cartella app/controllers
.
Modificare un prodotto
La vista che rappresenta la pagina di modifica è appviewsprodottosedit.html.erb
. Si attiva quando l'utente clicca sul link Modifica
(edit
). Vediamone rapidamente il comportamento:
- importa il valore del prodotto (
<%hidden_field 'prodotto','id'%>
); - visualizza i dati del prodotto in un form composta da 3 input di tipo
text
(marca, descrizione e quantità) già riempiti con i valori precedenti (es:@prodotto.marca
); - applica la modifica dopo l'invio del form e visualizzare la pagina "show";
- genera un blocco di errori nel caso di inserimento errato.
<% form_for(@prodotto) do |f| %> <%= hidden_field 'prodotto','id'%> <p><label for="prodotto_marca">Marca</label><br/> <input class="text" name="prodotto[marca]" size="30" type="text" value="<%= @prodotto.marca%>"/></p> </p> <p><label for="prodotto_descrizione">Descrizione</label><br/> <input class="text" name="prodotto[descrizione]" size="30" type="text" value="<%= @prodotto.descrizione%>"/></p> </p> <p><label for="prodotto_quantita">Quantià</label><br/> <input class="text" name="prodotto[quantita]" size="30" type="text" value="<%= @prodotto.quantita%>"/></p> </p> <%= f.submit "Modifica il prodotto" %> <% end %> <%= error_messages_for :prodotto %>
Aggiungere un foglio di stile
Nella cartella public/stylesheets
troviamo il file scaffold.css
generato con il comando scaffold
. Modificando il foglio di stile possiamo già conferire alle applicazioni un aspetto molto accattivante. Nel nostro caso abbiamo impostato colori differenti per i blocchi di codice e i blocchi in linea e abbiamo aggiunto alcune immagini, posizionate nella cartella public/images
.
Conclusioni
Con questo articolo abbiamo dimostrato come impostare, con poco sforzo, una semplice applicazione Web. Naturalmente c'è molto da approfondire, ma avere una visione di insieme può essere un buon punto di partenza.