ActiveRecord Migration撰寫方法

Adler @ 2014-10-22


開啟rails專案以後,常常會需要對資料庫進行更動,這時就必須依靠Migration的協助。啥?你說為什麼不直接用GUI介面操作資料庫嗎?等有20個以上的table,再這樣做也不遲。本篇列出在撰寫migration檔案時會用到的指令。

Method列表

針對table編修

create_table :table_name do |t|
    t.type :column_name
    # 例如 t.integer post_id
end

drop_table :table_name

rename_table :old_table_name, :new_table_name

change_table :table_name do |t|
    t.action :column_name
    # 例如 t.remove post_id
end

針對column編修

add_column :table_name, :column_name, :type, options
rename_column :table_name, :old_column_name, :new_column_name
remove_column :table_name, :column_name
add_index :table_name, :column_name, options
remove_index :table_name, :column_name

欄位屬性

在上面提到所有:type的部份,就是要填上欄位屬性。在此僅列出最常用的幾個:

:string, :limit => 255
# 有限長度的字串,可以設定長度多少
:text 
# 無限長度的字串,在裡面寫小說也可以
:integer, :limit => 11
# 整數,limit通常不會設定,預設為11,詳細請看延伸閱讀
:date
# 日期
:decimal, :precision => 3, :scale => 4
# 十進位數,就是有小數點的數字,precision代表小數點要幾位,而scale代表允許存入幾位數,[與二進位的float時常混淆](https://stackoverflow.com/questions/8514167/float-vs-decimal-in-activerecord)
:boolean
# 布林,單純的true和false

我忘了如何產生migrate檔案

複習一下,通常產生Migration有兩種方法,一個是產生model時一併產生的檔案,大概都是長這樣:

$ rails generate model post

另一種方法是用migration指令:

$ rails generate migration add_comments_to_post

這兩種方法都會產生migration檔案,存放在db/migrate資料夾底下。

檔案內容撰寫

我們打開model產生的migration檔案,大概是長這樣:

裡面使用create_table在資料庫中產生新的table。

當然我們也可以在這個create_table block的外面補充別的內容:

不管怎麼寫,最後就是在terminal進行$rake db:migrate來更動資料庫即可。

up & down

在Rails當中雖然預設都是用新式的change當做method,但有時會看到使用舊式的up和down當做method,為什麼呢?因為我們除了migrate以外也會執行rollback指令取消migrate,如果請Rails將資料庫倒車,不一定每次Rails都知道該怎麼做,所以我們利用up和down的寫法跟Rails說明要怎麼往前migrate和往後rollback。

一般來說,『新增』和『刪除』兩個動作都可以在change method裡面完成,只有在rename column或change column時才會有這個困擾。

# up代表往前migrate
def up
    change_column :post, :content, :text
end

# down代表往後rollback
def down
    change_column :post, :content, :string
end

# Rails 4 之後加入的新寫法,看起來比較美觀
def change
  reversible do |r|
    change_table :post do |t|
      r.up   { t.change :content, :text }
      r.down { t.change :content, :string }
    end
  end
end

嗯...不過我個人還是比較喜歡將up和down分開來寫比較簡單明瞭。如果真的很不確定Rails到底有沒有辦法rollback的時候,就用這個up和down方法來寫吧!

延伸閱讀

Decimal vs Float

Integer屬性的limit

Ruby on Rails實戰聖經