博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
migration
阅读量:5082 次
发布时间:2019-06-13

本文共 7773 字,大约阅读时间需要 25 分钟。

=========================== 如何写migration ========================= 

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  
这些方法替代使用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   

1、创建数据库表格

在创建Model后,Rails 自动的在/db/migrate文件夹中生成了 迁移编号_create_Model名.rb 格式的文件,如006_create_users.rb

打开该文件,做如下修改

class CreateUsers < ActiveRecord::Migration	  def self.up           #此处加入要创建的表格           create_table "users"  do |t|	      t.column :login,                     :string,  :null => false	      t.column :email,                     :string	      t.column :crypted_password,          :string, :limit => 40                                   # 字符长度限制	      t.column :salt,                      :string, :limit => 40	      t.column :created_at,                :datetime	      t.column :updated_at,                :datetime	      t.column :remember_token,            :string	      t.column :remember_token_expires_at, :datetime             t.column :flag,                      :boolean,   :null => false, :default => false            #设置默认值           end	  end	  def self.down	    drop_table "users"	  end	end  保存后,运行rake db:migration  这样就可以在config/database.yml 文件里配置的数据库中创建一个名为:users的数据库表,并且拥有相应的表字段。

2、修改数据库表格

如果需要修改之前已经创建好的数据库表,很多人习惯知道用GUI工具到数据库中直接做删除数据表、增加数据表字段、删除数据表字段以及修改一些字段的属性设置。当然这样做的效果是一样的,但是假如有那么一天我们所编写的程序因为之前对数据库进行了修改而产生了严重的BUG,我们必须将它修改回来,但是我们现在又忘记了原来的数据表的设置,那么这样就麻烦了。但是如果我们能够记录我们对数据库的每个操作,那么我们想回到哪个数据库版本都可以做到。这里做一个例子了说明:  (1)、删除数据库表,并重建一个新的数据库表	class ChangeAttachment < ActiveRecord::Migration	  def self.up	    drop_table :attachments                   # 删除数据库表	    create_table :attachments do |t|	      t.column "owner_id", :integer, :null => false	      t.column "owner_model", :string, :default => "", :null => false	      t.column "type", :string, :default => "", :null => false	      t.column "filepath", :string, :default => "", :null => false	      t.column "filename", :string, :default => "", :null => false	      t.column "type_flag", :string	      t.column "enable", :boolean, :default => true, :null => false	    end	  end	  def self.down	  end	end
(2)、增加索引     class AddColumnAndIndex < ActiveRecord::Migration	  def self.up	    add_index :systems,:client_id	    add_index :systems,:scale_length	    add_index :systems,:development_start_on	  end	  def self.down	    remove_index :systems,:client_id	    remove_index :systems,:scale_length	    remove_index :systems,:development_start_on	  end	end
(3)、增加数据表字段       class AddColumnToHolidayrecord < ActiveRecord::Migration	  def self.up	    add_column :holiday_records, :revert_flag, :boolean, :null => false, :default => false	  end	  def self.down	    remove_column :holiday_records, :revert_flag	  end       end
(4)、修改字段属性	class ChangeUserColumns < ActiveRecord::Migration	  def self.up	    change_column :users, :birthday,              :date	    change_column :users, :graduated_at,          :date	    change_column :users, :dimission_at,          :date	  end	  def self.down	    change_column :users, :birthday,              :datetime	    change_column :users, :graduated_at,          :datetime	    change_column :users, :dimission_at,          :datetime	  end	end  注意在上面例子中的关键字如:create_table,drop_table,add_index等等,这些方法决定了数据迁移将进行何种操作。

3、数据预先导入数据库

有些数据在项目移交后需要在数据库中生成基本一些数据,比如说一些地名,一些不变的数据,还有一些项目的初始数据。因为作为开发人员项目移交后我们不能把自己的数据库给用户,只能是用户创建好数据库后用数据迁移创建所需的数据表。但是那时数据库中没有任何数据,所以可以用数据迁移将我们所要的数据加入到数据库当中。比如下面的例子。	#初始数据       class CreateStateDatas < ActiveRecord::Migration	  def self.up	    State.create(:name=>'北海道')	    State.create(:name=>'青森県')	    State.create(:name=>'岩手県')	    State.create(:name=>'宮城県')	    State.create(:name=>'秋田県')	    State.create(:name=>'山形県')	    State.create(:name=>'福島県')	    State.create(:name=>'茨城県')	    State.create(:name=>'栃木県')	  end	  def self.down	  end	end
#批量修改数据	class ChangeUserNameFulltext < ActiveRecord::Migration	  def self.up	    users = User.find(:all)	    for user in users	      unless user.valid?	        user.name = "ユーザ名全角文字"	        user.save!	      end	    end	  end	  def self.down	  end	end

4、处理一些与数据库无关的操作

migration不仅仅可以做与数据库有关的各种操作,同样可以做些其他的操作,只是我们习惯用数据迁移来对数据库版本进行控制。这个方法我们不常用,如果需要用到我们可以写到self.up当中,而在self.down中写一个相反的操作代码。

5、migration的工作原理

有些人可能对migration的工作原理不了解。这里我简单的说明一下。每个迁移任务都有自己的编号,编号从1开始,后续的每个新的任务都会得到在原基础上加1的编号。Rails会记住最近一次作于数据库的 迁移任务编号,登记到/db/schema.rb中当你要求使用新的迁移任务来更新数据库结构,它会将所有可用的迁移编号与当前的数据库结构编号进行比较。只要找到编号比Rails所登记的最大编号还大的迁移任务,rake将运行该任务。这里要注意的是Rails只关注编号,而不关注你给迁移任务所取的任务名。

(1)、创建和运行迁移任务

命令:rake db:migration

(2)、回退到某个迁移任务版本

命令:rake db:migration version=10          这里是将迁移任务的版本回到10,注意version、= 、数字之间没有空格

(3)、解析迁移任务

每个迁移任务中都有up方法和down方法,如下	class ChangeUserNameFulltext < ActiveRecord::Migration	  def self.up	  end	  def self.down	  end	end
其中up()方法负责修改数据库,down()负责撤销这些修改,对应的编号管理中up()方法是从小到大的顺序执行,而down()则是由大到小的顺序执行。

转载于:https://www.cnblogs.com/mingforyou/archive/2012/09/20/2695488.html

你可能感兴趣的文章
[leetcode]Minimum Path Sum
查看>>
内存管理 浅析 内存管理/内存优化技巧
查看>>
hiho1079 线段树区间改动离散化
查看>>
【BZOJ 5222】[Lydsy2017省队十连测]怪题
查看>>
第二次作业
查看>>
【input】 失去焦点时 显示默认值 focus blur ★★★★★
查看>>
Java跟Javac,package与import
查看>>
day-12 python实现简单线性回归和多元线性回归算法
查看>>
Json格式的字符串转换为正常显示的日期格式
查看>>
[转]使用 Razor 进行递归操作
查看>>
[转]Android xxx is not translated in yyy, zzz 的解决方法
查看>>
docker入门
查看>>
Android系统--输入系统(十一)Reader线程_简单处理
查看>>
监督学习模型分类 生成模型vs判别模型 概率模型vs非概率模型 参数模型vs非参数模型...
查看>>
Mobiscroll脚本破解,去除Trial和注册时间限制【转】
查看>>
实验五 Java网络编程及安全
查看>>
32位与64位 兼容编程
查看>>
iframe父子页面通信
查看>>
ambari 大数据安装利器
查看>>
java 上传图片压缩图片
查看>>