對於Rails的遷移功能Migrations,一直都只是看一下網上的一些很基礎很基礎的代碼片段就開始動手寫代碼,對它的認識基本上就是停留在抄襲的層面,連會用都說不上.有感於此,終下決心要弄清楚Migrations,至少得會用啊,山寨抄襲終非王道.
學習Migrations最佳的學習資料莫過於 Ruby On Rails網站上的 Guides 系統文章了,連接在http://guides.rubyonrails.org/migrations.html
本文的不少代碼都是出自那裏.
在個人理解中,Migrations就是一個基於ruby,針對數據庫(SQL)的DSL,它的出現也是符合Rails中到處皆Ruby的原則的,正是專一於Ruby,這樣Rails才顯得別樣的美麗.
=========================== 如何寫migration =========================
javascript
每個migrate的類都是 ActiveRecord::Migration 的子類,每個migrate都要重寫兩個方法 up 和 down:
- class CreateProducts < ActiveRecord::Migration
- def self.up
-
- end
- def self.down
-
- end
- end
簡單的說 up 方法就是操做數據庫時用的,down就是你後悔了,用來回滾用的.
Migrations提供了一系列的方法來操做數據庫:
- create_table
- change_table
- drop_table
- add_column
- change_column
- rename_column
- remove_column
- add_index
- remove_index
具體各個方法的詳細定義,能夠查看Rails的API
http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
這些方法替代使用SQL來操做數據庫,固然也可使用 execute 方法直接使用 SQL 來操做數據庫,我的不推薦這種方式,可是在某些狀況下,提供直接使用SQL也是很方便的:
- execute <<-SQL
- ALTER TABLE products ADD CONSTRAINT fk_products_categories FOREIGN KEY (category_id) REFERENCES categories(id)
- SQL
定義字段有兩種方法:
-
- create_table :products do |t|
- t.column :name, :string, :null => false
- end
-
-
-
-
-
- create_table :products do |t|
- t.string :name
- end
除了這幾個經典的定義字段方法外,還有兩個特別的Helper方法:
-
- change_table :products do |t|
- t.timestamps
- end
-
-
- create_table :products do |t|
- t.references :category
-
-
- t.references :attachment, :polymorphic => {:default => 'Photo'}
- end
以上兩個方法是錦上添花之做,至關的實用.
除了使用以上方法操做數據庫外,其實還能夠直接在migration中使用 Model 的.好比:
- def self.up
-
-
- User.update_all ["receive_newsletter = ?", true]
- end
使用model的另一種狀況是:當前migration要刪除表中的一個字段 first_name,可是你的model中的某個方法使用了這個字段做爲驗證,好比:
- class User < ActiveRecord::Base
- validates_presence_of :first_name
- end
那麼當你要在migration中增長一條記錄時,這個驗證便不能經過,如:
- def self.up
- User.create({:name => 'name'}).save
- end
在這種狀況下,你能夠在migration中從新定義一個model:
- class XXXMigration < ActiveRecord::Migration
- class User < ActiveRecord::Base
- end
- def self.up
- remove_column :first_name
- end
-
-
- User.reset_column_information
-
- User.create({:name => 'name'}).save
===========================
migration文件的命名 =======================
按照Migration的約定去命名你的migration文件,會令你省很多功夫的,請千萬要相信這一點.
若是migration文件名是這樣的格式: AddXXXToYYY」 or 「RemoveXXXFromYYY
XXX => 字段名, YYY => 表名.
那麼migration生成的時候,Rails會自動爲你加上 add_column or remove_column
好比:
-
- class AddPartNumberToProducts < ActiveRecord::Migration
- def self.up
- add_column :products, :part_number, :string
- end
- def self.down
- remove_column :products, :part_number
- end
- end
-
- class RemovePartNumberFromProducts < ActiveRecord::Migration
- def self.up
- remove_column :products, :part_number
- end
- def self.down
- add_column :products, :part_number, :string
- end
- end
cool吧??
===========================
如何執行migration =========================
執行migration的經典方法:
- rake db:migrate
-
-
- rake db:migrate VERSION=20080906120000