Rails提供的gem ActiveRecord可說是資料庫操作的神器,資料庫結構簡單時查詢、寫入、操作都可以直接在rails console執行。不過當進行migration時,如果檔案內部沒有寫好,在migrate指令下去時,可能不小心造成整個壞掉的情況。
每一次Rails對資料庫進行更改,都是從migration檔案進行,因此每一次的更動都會有一個新的migration檔案。
本篇簡單說明幾個撰寫的指令,讓各位大概了解操作情況。
在Command Line當中,我們可以利用指令產生migration檔案。首先是從產生model的指令進行:
$ rails g model post
post是model名稱,也就是我們在Rails當中新增項目時,會寫入的table名稱。
這個指令會產生兩個重要部分,一個是在model資料夾中產生post.rb檔案,主要進行rails的關聯及其他操作;另一個是產生migration檔案,讓我們針對資料庫進行變更。假如我們已經有資料庫和內容了,只需要一個model讓我們可以讀取資料庫即可,那可以在產生model檔案的時候取消migrate:
$ rails g model post --migration=false
並在model檔案中加上:
self.table_name = "my_existing_table"
這樣就只會產生model檔案,也不需要再進行migrate。
雖然產生model檔案很方便,但常常還是需要對資料庫進行操作,包括欄位命名更改、屬性更改、刪除欄位等等,就是使用其他的migration檔案對資料庫進行操作。
$ rails g migration add_content_to_post
以上紅字的部份是檔名,可以隨意更動。我們接著就可以在migration檔案裡面進行撰寫,由於本篇以說明command line指令為主,詳細的內容撰寫可參考後續的文章。
利用rake指令進行migrate
在創造一個model或migration以後,必須進行migrate指令,才能啟動rails server,否則會出現Migration Pending的錯誤。也就是說Rails server必須在資料庫已完全更新的情況下才能使用。
$ rake db:migrate
他會依照我們在migration檔案中的描述來更動資料庫,例如新增或刪除欄位。
如果在執行完rake db:migrate指令以後才發現欄位名稱寫錯了,要重跑一次,要怎麼做呢?資料庫的操作與一般修改程式不同,一般我們只要回去程式碼上修改,再執行一次就可以了。但Rails資料庫的操作必須是:
有另一種替代方案是直接產生新的migration檔案進行修改,但由於未來migration檔案會越來越多,強烈不建議這麼做。簡單的狀況最好就用rollback解決就好,就像活到一定歲數以後就會覺得錢能解決的事情都是小事一樣。
不過並非所有migration都可以直接rollback,因為Rails在這方面還沒這麼聰明,必須倚靠我們在撰寫migration內部時,寫清楚說如果要rollback就要做什麼樣的事情。詳細撰寫方法可參考後續文章。
一般來說都是在網頁介面中新增資料,但如果已經有知道要新增的資料,那可以到seed.rb這個檔案中新增,利用create方法可以將東西都寫出來,接著在command line中執行:
$ rake db:seed
他就會去執行seed.rb檔案,將檔案新增到資料庫中。不過這真的是Rails的一個convention而已,seed.rb你裡面要寫什麼都沒關係,Ruby語法也可以隨意使用,並沒有特別的規範。只是不要亂寫即可,這樣後續維護會很困難,既然他叫做seed,那就是只寫我們要新增到資料庫的檔案即可。
如果migration真的玩到整個壞了,回復也回復不了,不知道到底哪個migration檔案是正確的,哪個檔案是錯誤的,那最快的方法是當下記錄起來自己到底要整個資料庫長什麼樣,然後果斷的執行:
$ rake db:drop db:create
首先,migration指令是可以串在一起執行的。db:drop會將資料庫整個刪除,然後db:create會開啟一個全新且乾淨的資料庫。接著如果你真的搞砸了,可以把schema.rb內容整個清掉,然後把migration檔案全部刪除,再下$ rails g miration init指令,產生一個migration檔案,接著把所有需要的table、欄位寫入。最後執行:
$rake db:migrate
就大功告成。
如果只是一個migration壞了,又無法rollback,那就是修改migration檔案成我們要的樣子以後,有幾個執行方法:
$ rake db:migrate:reset
這個指令包含了db:drop、db:create、db:migrate指令,有需要的話再額外跑db:seed檔案即可。
$rake db:reset
包含了db:drop、db:create、db:schema:load、db:seed,這個方法的重點在於並沒有使用migration檔案,可能要注意一下,如果你確定你的schema.rb檔案裡面的資料是正確的,就跑這個。
其實這個指令開發者不太常使用到,因為是包含在db:migrate和其他指令當中的。主要有兩個指令:
$ rake db:schema:load
我們在進行migration時,Rails會依照尚未執行的migration檔案來進行資料庫操作,並寫用現有的資料庫建構出一個schema.rb檔案,如果我們打開這個檔案,就會看到裡面有我們整個資料庫的table、欄位、屬性等詳細資料。
因此,rake db:schema:load這個指令會依照schema.rb檔案裡面的描述,把資料庫裡面建構成schema.rb裡面指定的模樣。注意,他純粹只有建構而已,裡面並不會有任何資料,而且任何既存的資料都會被清除。
為什麼這個指令我們不會用到呢?因為不管是新增資料庫、打掉重練,都已經將這個指令包含在裡面,也就是說不管是db:reset、db:setup,都會執行這個指令。一般來說我們不用特別把這個指令再拿出來執行一次。
Stackoverflow上也有相關討論。
$ rake db:schema:dump
在Stackoverflow當中有提到,db:schema:dump其實是db:migrate裡面程序的一環,也就是說進行rake db:migrate時,會進行以下幾個動作:
也就是說,他和db:schema:load的順序是相反過來的,一般來說都是包含在migrate指令裡面,同樣也不需要再拿出來執行一次。除非...真的有狀況我們把schema.rb改壞了(誰沒事要去改那個檔案?),然後也沒有做版本控制(誰到今天了還不做版本控制?),那我們就會需要這個指令。否則...先看看就好。
CC授權圖片:barrymieny