首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > Ruby Rails >

The Ruby On Rials Gudie - Active Record Migrations

2013-10-29 
The Ruby On Rials Gudie -- Active Record Migrations中文就是数据迁移,它是用来更改数据库的,但是它有一

The Ruby On Rials Gudie -- Active Record Migrations

中文就是数据迁移,它是用来更改数据库的,但是它有一个挺好的设计,就是他会记录你更改的历史,你每次修改都会单独生成一个文件,然后在前一个的基础上修改。这样假如你发现了设计中的失误,那么你可以回滚到你觉得正确的版本上去。并且它的修改不是SQL级别,它是Ruby SDL级的。你的db/schema.rb反映了你的表


下面给一个小例子

classCreateProducts < ActiveRecord::Migration  defchange    create_table:productsdo|t|      t.string:name      t.text:description       t.timestamps    end  endend

这个就是一个migration(以后我们就用这个英文词,因为中文翻译的感觉很怪,并且你以后命令也少不了用这个词什么的,早点熟悉),它创建了一个products的表。这样就ok了

具体描述这个表原英文是这样的,很简单,就不翻译了。注意它自动生成了id这个primary key,还有因为timestaps新加了两列

This migration adds a table called products with a string column called name and a text column called description. A primary key column called id will also be added implicitly, as it's the default primary key for all Active Record models. The timestamps macro adds two columns, created_atand updated_at. These special columns are automatically managed by Active Record if they exist.


创建一个Migration


我们的migration生成的文件名字格式是这样的 YYYYMMDDHHMMSS_create_products.rb 解释下, 第一个下划线前的是UTC时间(不理解UTC没关系的,知道它是个时间戳就ok了,能够反映我们这个文件的创建的日期),第一个和第二个下划线间的是操作名(我们这里是创建,以后还可以有很多操作),第二个下划线后的是表的名字(注意,这里是复数形式,这个就体现出来了rails的命名规则的变化了,还是很有意思的,他是复数,那么就说明他是表)。


假如我们生成一个自己的Migration,其实很简单的,参考下面的命令

rails generate migration AddPartNumberToProducts

这个就ok了,他会生成一个类似的名字YYYYMMDDHHMMSS_add_part_number_to_products.rb的文件,这里进行了个命名规则的变化(其实也很简单,在rails中,model是采用驼峰式命名规则,而其余的是采用下划线的明明规则,更准确的说是只要要求大写的,是采用驼峰式命名规则的,其余的都是用下划线的),这个文件中像下面的一样

classAddPartNumberToProducts < ActiveRecord::Migration  defchange  endend

这是一个空的migration,我们的操作是change里面的操作,只要从里面写出来就行了。


具体几类操作:

一. create一个表


命令就是这样的

rails generate migration CreateProducts

这是最主要的命令,他会生成一个这样的文件

classCreateProducts < ActiveRecord::Migrationdefchange

end

end

假如你想创建一个带有name和part_number列的表,你可以修改这个文件为下面的,就ok了,他们的属性是文本

classCreateProducts < ActiveRecord::Migration  defchange    create_table:productsdo|t|      t.string:name      t.string:part_number    end  endend

很简单吧,其实还可以更简单,这样一个命令,足矣

rails generate migration CreateProducts name:string part_number:string

功效是一样的


二. 增加一个column,这个也很简单

rails generate migration AddDetailsToProducts part_number:string price:decimal

这样子他就生成了

classAddDetailsToProducts < ActiveRecord::Migration  defchange    add_column:products,:part_number,:string    add_column:products,:price,:decimal  endend这样一个文件,就增加了两个列,当然,你也可以

rails generate migration AddDetailsToProducts

然后在修改的了

假如你想在新的列上家一个索引,那么也可以这样执行的

rails generate migration AddPartNumberToProducts part_number:string:index

这样他就增加了一个part_number的列了,并且加上了索引

生成了下面的一个文件

classAddPartNumberToProducts < ActiveRecord::Migration  defchange    add_column:products,:part_number,:string    add_index:products,:part_number  endend


三. 删除一列

rails generate migration RemovePartNumberFromProducts part_number:string

这样就删除了part_number这个列

生成了这样文件

classRemovePartNumberFromProducts < ActiveRecord::Migration  defchange    remove_column:products,:part_number,:string  endend

总结下,对于命令解释下吧(小技巧,g可以代替generate)

创建表:rails g migration CreateXXX 后面可以跟着列的名字和对应的格式

增加列:rails g migration AddXXX后面可以跟着列的名字和对应的格式加上:index的话就可以加一个索引

删除列:rails g migration RemoveXXX 后面可以跟着列的名字和对应的格式

其实区别就是第一个单词,记住一定要使用驼峰命名规则,rails讲究是约定优于规则,遵守rails的命名规则书写规则什么的,rails才会更好的和你玩


手写migration

虽然rails的migration很神奇,有人甚至说这是rails的魔法,但是我们还是要手写migration来真正明白它是做了怎么回事,我们所书写的全部是要在那个migration 的file中的change中的。


1. 先说创建表,用的函数是create_table

用法

create_table:productsdo|t|  t.string:nameend

这样就创建了一个有一个类型为文本名字为name的名叫products的表,很简单。对了,他会默认的创建一个叫id的列,类型是数字类型,作为主键的。

2. 创建一个join表,就是建立两个表的级联

create_join_table:products,:categories

这样就创建了一个表叫做categories_products 假如你想自己定义名字的话就用下面的

create_join_table:products,:categories, table_name: :categorization这样就ok了

这个表中有两列,并且非空。叫做product_id和category_id(注意是单数形式)。当然那你可以自己定义一些列的属性

这样用

create_join_table:products,:categories, column_options: {null: true}在column_options中设定

3.修改一个表changing tables

用的方法叫change_table,他遍历整个数据,然后进行修改

change_table:productsdo |t|  t.remove:description,:name #移除description 和 name 列  t.string:part_number # 增加一个string类型叫做part_number的列  t.index:part_number #为part_number的列加上索引  t.rename:upccode,:upc_code #修改upccode列的名字为upc_codeend


t提供了很多方法,比如remove,index,rename。分别是移除,加上索引,重民名,而那个string是声明了一个part_number的列,具体的我从上面注释了

4. 直接执行sql

Products.connection.execute('UPDATE `products` SET `price`=`free` WHERE 1')

这里你创建的model叫product,所以你的数据库中的表是products,而这个貌似是也有点model的意思,所以大写了。所以这样就可以执行啦


总之 修改表可以使用的方法如下,只有这些方法是支持回滚的

  • add_column
  • add_index
  • add_reference
  • add_timestamps
  • create_table
  • create_join_table
  • drop_table (must supply a block)
  • drop_join_table (must supply a block)
  • remove_timestamps
  • rename_column
  • rename_index
  • remove_reference
  • rename_table当我们使用migration做的事情很复杂时,我们想回滚,有些migration不知道该如何做的,我们可以用更加复杂的reversible来说明如何做

    一个例子通过这个例子,我们要明白的只有两个事,up和down,up就是你执行它的时候如何办,down就是回滚时如何办

    classExampleMigration < ActiveRecord::Migration  defchange    create_table:productsdo |t|      t.references:category    end     reversibledo|dir|      dir.updo        #add a foreign key        execute <<-SQL          ALTERTABLE products            ADDCONSTRAINT fk_products_categories            FOREIGNKEY (category_id)            REFERENCEScategories(id)        SQL      end      dir.downdo        execute <<-SQL          ALTERTABLE products            DROPFOREIGN KEY fk_products_categories        SQL      end    end     add_column:users,:home_page_url,:string    rename_column:users,:email,:email_address  end
    这个是rails 4.0 中的新写法,同样支持以前的rails的书写方法,就是吧up和down直接卸载change下面例如下个例子

    classExampleMigration < ActiveRecord::Migration  defup    create_table:productsdo |t|      t.references:category    end     # add a foreign key    execute <<-SQL      ALTERTABLE products        ADDCONSTRAINT fk_products_categories        FOREIGNKEY (category_id)        REFERENCEScategories(id)    SQL     add_column:users,:home_page_url,:string    rename_column:users,:email,:email_address  end   defdown    rename_column:users,:email_address,:email    remove_column:users,:home_page_url     execute <<-SQL      ALTERTABLE products        DROPFOREIGN KEY fk_products_categories    SQL     drop_table:products  endend

    其实这个回滚还是有其他的写法的,但是我觉得这种就足够用了,还有一种可以用其他版本的reversible函数的方法,不过感觉很鸡肋,第一很难说能用到,第二这样开发不同版本间的依赖性太高了,不好。有兴趣可以查看下。


    运行migration


    用法很简单

    rake db:migrate

    这样将按顺序执行还没有被migrate的migration

    rake db:migrate VERSION=20080906120000

    这样他将执行特定时间戳的版本



    回滚

    rake db:rollback

    回滚一步

    rake db:rollback STEP=3

    回滚三步



    重置数据库

     rake db:reset



    在特定环境中执行

    rake db:migrate RAILS_ENV=test


    其他的还有一些比如执行特定migration的up或者down函数啊,修改输出信息啥的。用的机会不大,不再单独写出。



热点排行