Migration

Creating and Running Migration

在每一個migration file 的前面,有一個三位數的數字,和一個underscore,這個三位數的數字是migration在應用時的版本值。

我們可以餵了新增一個column而新增一個migration file,如此是為了version control。可是當file 多時,會否管理又是一個問題?

當執行rake db::migrate時,這個task首先會檢查db中的schema_info table,以取得目前的version。如果schema_info不存在,則會建立這個table,並設定version 這個column的值為0。

在schema_info這個table中,只有一個column,column name為version。也只有一個row,存放目前的migration version。

如果schema_info table以存在,rails會將值讀出來,然後檢查db/migrate 目錄中所有檔案,是否有檔案的名稱的首三位數字比schema_info table中的version數字大的,如果有,則依序執行他,並改變db。當完成後,便將最後一個數字存入schema_info table中。

強制migrate到某個版本:rake db:migrate VERSION=10

如果數字大於目前的版本,則會將db/migrate目錄中,首三碼的數字是介於目前的版本號碼到指定號碼間的檔案,由小到大執行up method,修改db。

如果數字小於目前的版本,則會將db/migrate目錄中,首三碼的數字是介於目前的版本號碼到指定號碼間的檔案,由大到小執行down method,修改db。

最後都會將schema_info version的數字改為最後執行的編號。




Anatomy of a Migration




Migration class是ActiveRecord::Migration的subclass,其中需包含兩個method up 與 down。




Migration 支援的column type: binary, bo0lean, date, datetime, decimal, float, integer, string, text, time, timestamp。




每一個column有一些選項可以坐設定:

:null => true/false 如果是false,則該column不可以是null。

:limit => size 設定這個column的值得size,例如string的字元數。

Default => value 設定預設值。

在decimal這個column type另有兩個選項可以設定:precision /scale

:precision => 5 定義這個數字有幾位數

:scale => 2 定義小數點後有幾位

ex. add_column rders, :price, :decimal, :precision=>8, :scale=>2

其範圍是999999.99~-999999.99


add_column rders, :placed_at, :datetime, :default=>Time.now

因為default value只會在migrate執行時計算一次,所以上述的statement的預設值都是一樣的時間,就是migrate的時間。

如果要解決這個問題,只需將此column name設為created_at,type設為timestamp。


















Renaming Column

我們可以利用rename_column來修改column name。

ex. rename_column rders, :e_mail, :customer_email

其中第一個參數是table name,第二個是舊名稱,第三個是新名稱




Changing Columns

利用change_column method,我們可以修改column type,以及改變某個column的選項。

ex. 將某個type為integer的column改為integer。

def self.up

change_column rders, rder_type, :string, :null=>false

end

如此一來,原本在這個column中的數字,就會被改為字串,ex. 123=> '123'




那self.down我們要怎麼寫呢?我們可以很直覺得寫

change_column rders, rder_type, :integer

可是這樣會有一個問題,就是如果我們在這個column中有不是數字的值,那該怎麼辦,如果這個column可以接受null,那也許不是問題,可是如果不行呢?




這個時候我們就要讓這個migration成為不能回復的動作,Rails提供了一個特別的exception。

def self.down

raise ActiveRecord::IrreversibleMigration

end




Managing Table


Class CreateOrderHistories < ActiveRecord::Migration

def self.up

create_table rder_histories do |t|

t.column rder_id, :integer, :null=>false

t.column :create_at, :timestamp

end

end

def self.down

drop_table rder_histories

end

end







create_table method 會取得一個table name 與一個block,這個block會透過一個表格定義物件(Table definition object)來定義每一個column。




在create_table中,Migration會自動加入id這個column,並設定為primary key,所以我們無須另外定義。




在create_table中我們可以加入一些選項做設定:

force => true, migration在建立這個table前會先將同名的table刪除。

转自
http://tw.myblog.yahoo.com/weijenlu/article?mid=31&prev=33&next=30&l=a&fid=9

你可能感兴趣的:(Yahoo,UP,Rails,ActiveRecord)