Per capire come il sistema di migrazione renda possibile cambiare a piacimento la versione del database in uso, analizziamo il primo file di migrazione; apriamo il file create_bookmarks
:
class CreateBookmarks < ActiveRecord::Migration def self.up create_table :bookmarks do |t| t.string :url t.string :title t.text :description t.timestamps end end def self.down drop_table :bookmarks end end
Notiamo innanzitutto che sono presenti due metodi: self.up e self.down. Queste due funzioni descrivono i passi che devono essere compiuti per avanzare di una versione nel database e per tornare alla versione precedente.
In questa migrazione la funzione self.up
richiede la creazione della tabella bookmarks (create_table :bookmarks
) con i campi url
di tipo string
, title
di tipo string
e description
di tipo text
. Viene infine richiesta, tramite l'istruzione t.timestamp
, la creazione di due campi, created_at
e updated_at
, nei quali vengono salvati automaticamente data e ora di creazione e data e ora di ultima modifica di ogni record.
t.string
e t.text
indicano il tipo di campo che vogliamo creare; per la creazione dei campi possiamo scegliere diversi tipi, ecco i principali:
Tipo | Descrizione |
---|---|
:string |
stringa di testo, corrisponde al varchar in SQL |
:text |
stringa di testo di lunghezza indefinita |
:integer |
intero positivo |
:decimal |
numero decimale |
:datetime |
data e ora |
:time |
data |
:date |
ora |
:boolean |
booleano |
È possibile inserire anche alcune opzioni per ogni colonna indicata nel file di migrazione:
Opzione | Descrizione |
---|---|
null |
indica se una colonna accetta valori nulli (:null => true )oppure no ( :null => false ).se non esplicitato la colonna accetta valori nulli |
default |
indica il valore di default attribuito ai campi della colonna |
length |
la lunghezza massima |
Supponiamo di voler aggiungere a ogni bookmark un voto da 1 a 5; per implementare questa funzionalità sarà necessario creare un nuovo campo nella tabella bookmarks per ospitare il voto. Posizioniamoci con il terminale nella cartella del nostro progetto Rails e creiamo una nuova migrazione in cui descriveremo le modifiche al database che volgiamo effettuare. Digitiamo:
$ ruby script/generate migration add_rate_to_bookmarks exists db/migrate create db/migrate/20080608125754_add_rate_to_bookmarks.rb
Il risultato a video ci informa della creazione del nuovo file 20080608125754_add_rate_to_bookmarks.rb
; il file ha il nome che abbiamo indicato (add_rate_to_bookmarks
) preceduto dal timestamp della sua creazione. Apriamo il file e individuiamo i metodi self.up
e self.down
, per ora vuoti.
class AddRateToBookmarks < ActiveRecord::Migration def self.up end def self.down end end
Nel metodo self.up
inseriamo l'istruzione per la creazione di una nuova colonna all'interno della tabella già esistente:
def self.up add_column :bookmarks, :rate, :integer, :null => false, :default => 3 end
Con l'istruzione add_column
abbiamo richiesto la creazione di una colonna dal nome rate
di tipo integer
(interno positivo), non nullo e con valore di default 3. Non ci rimane che compilare il metodo self.down
per indicare le azioni da compiere per annullare le operazioni del metodo self.up
:
def self.down remove_column :bookmarks, :rate end
È importante compilare sempre in modo parallelo il metodo self.up
e self.down
nelle migrazioni, le istruzioni contenute nei due metodo devono sempre annullarsi: alla creazione di una nuova colonna in self.up
deve corrispondere la cancellazione della colonna in self.down
, alla creazione di una nuova tabella in self.up
deve corrispondere l'eliminazione dell'intera tabella in self.down
.
Aggiorniamo ora il database all'ultima versione disponibile con il comando rake db:migrate
:
$ rake db:migrate == 20080608125754 AddRateToBookmarks: migrating =============================== -- add_column(:bookmarks, :rate, :integer, {:null=>false, :default=>3}) -> 0.3209s == 20080608125754 AddRateToBookmarks: migrated (0.3214s) ======================
La tabella è stata aggiornata e per controllare il risultato avviamo la console Rails e verifichiamo l'esistenza del nuovo attributo rate per tutti i bookmark.
$ ruby script/console Loading development environment (Rails 2.1.0) >> b = Bookmark.find(:first) => #<Bookmark id: 1, url: "http://ruby.html.it", title: "Ruby su HTML.it", description: "Home page della sezione Ruby. Guide, articoli di ap...", created_at: "2008-06-02 00:20:12", updated_at: "2008-06-02 00:20:12", rate: 3> >> b.rate => 3 >> b.rate = 5 => 5 >> b.save => true
Per annullare l'operazione di inserimento della nuova colonna basterà invocare il comando rake db:migrate VERSION=...
indicando come versione quella precedentemente a quella appena applicata.