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 :orders, :price, :decimal, :precision=>8, :scale=>2

其範圍是999999.99~-999999.99


add_column :orders, :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 :orders, :e_mail, :customer_email

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


Changing Columns

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

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

def self.up

change_column :orders, :order_type, :string, :null=>false

end

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


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

change_column :orders, :order_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 :order_histories do |t|

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

t.column :create_at, :timestamp

end

end

def self.down

drop_table :order_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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值