对于Rails的迁移功能Migrations,一直都只是看一下网上的一些很基础很基础的代码片断就开始动手写代码,对它的认识基本上就是停留在抄袭的层面,连会用都说不上.有感于此,终下决心要弄清楚Migrations,至少得会用啊,山寨抄袭终非王道.
学习Migrations最佳的学习资料莫过于 Ruby On Rails网站上的 Guides 系统文章了,链接在http://guides.rubyonrails.org/migrations.html
本文的很多代码都是出自那里.
在我的理解中,Migrations就是一个基于ruby,针对数据库(SQL)的DSL,它的出现也是符合Rails中处处皆Ruby的原则的,正是专注于Ruby,这样Rails才显得别样的美丽.
=========================== 如何写migration =========================
每一个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
- 0赞
原文地址: http://www.javaeye.com/topic/423860