Rails Migrations

Posted on Sat, 2006-09-09 by paranoid

Svi koji se bave web aplikacijama su prije ili kasnije rucno slagali bazu tipkajuci SQL. Ili su bar koristili neki software koji je to radio umjesto njih (valjda, prica se da tako nesto postoji). Prednost rada sa Railsom je da se DB schema moze sloziti i u cistom rubyu. Vjerujem da nije potrebno reci zasto je to dobro?

Ok, ipak budem:

  • pise se jednom
  • radi na bazama koje su podrzane od strane Railsa (mysql, pgsql, sqlite...)
  • schema se moze drzati pod odredjenom verzijom migracije

Vrijeme je za jedan lagani primjer. Najlaksi nacin za kreiranje nove migracije:

cd /my/rails_app/
./script/generate migration create_users

Skripta ce u ovom slucaju generirati file db/migrate/001createusers.rb koji ce izgledati 'vako:

class CreateUsers < ActiveRecord::Migration
    def self.up
    end

    def self.down
    end
end

Ukratko ovo je tek osnovna klasa sa dvije definirane funkcije: up i down. Up se poziva kada migracija ide na verziju vecu od one definirane u bazi. Mislim da je vise nego ocito kada se down funkcija poziva. :)

Kako rails zna koja verzija scheme je aktualna? Kada se prvi put vrti migracija rails automagically kreira i schema_info tablicu sa samo jednim poljem naziva version u koje se sprema trenutna verzija scheme. Inicijalno je vrijednost polja 0 (prazna baza). U gornjem primjeru kreirana je schema sa verzijom 1 (001createusers.rb). Iduca ce biti 002 i tako dalje.

Vratimo se na primjer. Ajmo slozit tablicu za juzere.

 def self.up
    create_table :users do |t|
        t.column :name, :string, :null => false
        t.column :email, :string
        t.column :password, :string, :null => false
    end
end

 def self.down
     drop_table :users
 end

Ova nadasve jednostavna migracija ce kreirati tablicu users sa 'name', 'email' i 'password' varchar(255) poljima. Down funkcija je jednostavna, dropa tablicu.

Nakon svega ovog potrebno je pokrenuti 'rake db:migrate' i voila! Imamo users tablicu.

No sto ako nakon nekog vremena odlucimo da bi mogli dodati jos jedno polje u tablicu? Recimo da se netko sjetio da bi bilo dobro dodati salt polje za slaganje passworda. Kreiramo novu migraciju i dodamo slijedece u dobiveni file:

def self.up
    add_column :users, :salt, :string
end

def self.down
    remove_column :users, :salt
end

Potrebno je jos jednom zavrtiti 'rake db:migrate' i tablica je na najnovijoj verziji. Kada smo vec kod verzija, ako je potrebno vratiti tablicu na prethodno stanje treba samo dodati VERSION=x kod pozivanja db:migrate (as in 'rake db:migrate VERSION=0' za cistu bazu).


Dado said on Mon, 2006-09-18:

Thumbs up za RSS!

paranoid said on Thu, 2006-09-21:

;) Nego, imo si pravo da se ovaj 'dizajn' očajno vidi na LCDovima, možda nešto i napravim po tom pitanju.

Nego, daj složi neku ikonu ili nešto da mogu stavit 'Disapproved by Kezele' :)

Dado said on Sun, 2006-09-24:

Kad se isključi CSS super je. :-D