Ruby on Rails 之旅(七)—— Ruby on Rails 入門(6)

對於Rails的遷移功能Migrations,一直都只是看一下網上的一些很基礎很基礎的代碼片段就開始動手寫代碼,對它的認識基本上就是停留在抄襲的層面,連會用都說不上.有感於此,終下決心要弄清楚Migrations,至少得會用啊,山寨抄襲終非王道. 

學習Migrations最佳的學習資料莫過於 Ruby On Rails網站上的 Guides 系統文章了,連接在http://guides.rubyonrails.org/migrations.html 
本文的不少代碼都是出自那裏. 

在個人理解中,Migrations就是一個基於ruby,針對數據庫(SQL)的DSL,它的出現也是符合Rails中到處皆Ruby的原則的,正是專一於Ruby,這樣Rails才顯得別樣的美麗. 

=========================== 如何寫migration ========================= 

javascript


    1.migration的結構 

每個migrate的類都是 ActiveRecord::Migration 的子類,每個migrate都要重寫兩個方法 up 和 down: 
Ruby代碼 
  1. class CreateProducts < ActiveRecord::Migration   
  2.   def self.up   
  3.      #想幹嗎,就幹嗎  
  4.    end    
  5.    def self.down   
  6.       #你後悔的時候,你會怎麼作?   
  7.     end   
  8. end   

簡單的說 up 方法就是操做數據庫時用的,down就是你後悔了,用來回滾用的. 


    2.migration提供調用的方法 

Migrations提供了一系列的方法來操做數據庫: 
Ruby代碼 
  1. create_table  #建表  
  2. change_table  #修改表結構  
  3. drop_table    #刪除表  
  4. add_column    #增長字段  
  5. change_column #修改字段定義  
  6. rename_column #修改字段名  
  7. remove_column #刪除字段  
  8. add_index     #建立索引  
  9. remove_index  #刪除索引  

具體各個方法的詳細定義,能夠查看Rails的API  http://api.rubyonrails.org/classes/ActiveRecord/Migration.html 
這些方法替代使用SQL來操做數據庫,固然也可使用 execute 方法直接使用 SQL 來操做數據庫,我的不推薦這種方式,可是在某些狀況下,提供直接使用SQL也是很方便的: 
Ruby代碼 
  1. execute <<-SQL   
  2. ALTER TABLE products ADD CONSTRAINT fk_products_categories FOREIGN KEY (category_id)  REFERENCES categories(id)    
  3. SQL   



    3.字段 

定義字段有兩種方法: 
Ruby代碼 
  1. #這個是傳統的方法  
  2. create_table :products do |t|   
  3. t.column :name:string:null => false   
  4. end   
  5.   
  6. #這個剛出來的時候,你們都說很性感,其實不外乎就是定義一系列的快捷方法: string,  
  7. # text, integer, float, decimal, datetime, timestamp, time, date,  
  8. # binary, boolean . 這一系列的方法對應各類數據類型,  
  9. # 還有 primary_key 方法是用來定義主鍵的.  
  10. create_table :products do |t|   
  11. t.string :name   
  12. end   

除了這幾個經典的定義字段方法外,還有兩個特別的Helper方法: 
Ruby代碼 
  1. #如下這個方法會自動在表中增長 created_at,updated_at這兩個類型爲timestamp的字段  
  2. change_table :products do |t|   
  3. t.timestamps   
  4. end   
  5.   
  6. #這個方法是定義關於關係的,可是不會爲你的表加上外鍵約束,若是你加上約束,請另外手動添加,切記!  
  7. create_table :products do |t|   
  8. t.references :category # 生成 category_id  
  9.   
  10. #這個是關聯關係中多態的定義,生成兩個字段 attachment_id 和 attachment_type ,而且attachment_type的默認值爲 'Photo'  
  11. t.references :attachment:polymorphic => {:default => 'Photo'}   
  12. end   

以上兩個方法是錦上添花之做,至關的實用. 


    4.在migration中使用 Model 

除了使用以上方法操做數據庫外,其實還能夠直接在migration中使用 Model 的.好比: 
Ruby代碼 
  1. def self.up  
  2. #直接就用model來更新數據庫,  
  3. #你能夠看到 migration 一直在提供便利讓你避免使用SQL,固然不是說SQL很差,只是想讓你更加的統一,只要ruby就行了.    
  4. User.update_all ["receive_newsletter = ?"true]   
  5. end   


使用model的另一種狀況是:當前migration要刪除表中的一個字段 first_name,可是你的model中的某個方法使用了這個字段做爲驗證,好比: 
Ruby代碼 
  1. class User < ActiveRecord::Base  
  2.     validates_presence_of :first_name  
  3. end  

那麼當你要在migration中增長一條記錄時,這個驗證便不能經過,如: 
Ruby代碼 
  1. def self.up   
  2. User.create({:name => 'name'}).save   
  3. end   

在這種狀況下,你能夠在migration中從新定義一個model: 
Ruby代碼 
  1. class XXXMigration < ActiveRecord::Migration   
  2. class User < ActiveRecord::Base   
  3. end  
  4. def self.up  
  5. remove_column :first_name  
  6. end  
  7.   
  8. #這個方法的做用就是取得最新的表定義  
  9. User.reset_column_information   
  10. #放心吧,這個User不會有 validates_presence_of :first_name 的驗證  
  11. User.create({:name => 'name'}).save  


===========================  migration文件的命名 ======================= 

按照Migration的約定去命名你的migration文件,會令你省很多功夫的,請千萬要相信這一點. 
若是migration文件名是這樣的格式: AddXXXToYYY」 or 「RemoveXXXFromYYY 
XXX => 字段名, YYY => 表名. 
那麼migration生成的時候,Rails會自動爲你加上 add_column or remove_column 
好比: 
Ruby代碼 
  1. #留意類名  
  2. class AddPartNumberToProducts < ActiveRecord::Migration   
  3. def self.up   
  4. add_column :products:part_number:string    
  5. end    
  6. def self.down   
  7. remove_column :products:part_number    
  8. end   
  9. end   
  10.   
  11. class RemovePartNumberFromProducts < ActiveRecord::Migration   
  12. def self.up   
  13. remove_column :products:part_number    
  14. end    
  15. def self.down   
  16. add_column :products:part_number:string    
  17. end   
  18. end   

cool吧?? 

===========================  如何執行migration ========================= 

執行migration的經典方法: 
Ruby代碼 
  1. rake db:migrate  
  2.   
  3. #執行特定版本  
  4. rake db:migrate VERSION=20080906120000   
相關文章
相關標籤/搜索