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   
相关文章
相关标签/搜索