Ruby on Rails - 迁移
Ruby on Rails - 数据库迁移 (Migrations)
Section titled “Ruby on Rails - 数据库迁移 (Migrations)”Rails Migrations 是一种管理数据库模式随时间变化的方式。您不是直接编写 SQL DDL (数据定义语言),而是使用 DSL (领域特定语言) 在 Ruby 中定义模式变更。这使得您的模式变更(大部分情况下)与数据库无关,并且可以随应用程序代码一起进行版本控制。
使用迁移的好处:
- 协作:如果一个开发者进行了模式变更,其他开发者可以通过运行
rails db:migrate更新其本地数据库。 - 部署:简化了部署过程中更新生产数据库模式的过程。
- 版本控制:模式变更成为您代码库的一部分,并在版本控制(例如 Git)中被跟踪。
- 数据库独立性:迁移抽象化了许多特定于数据库的 SQL 语法。
常见迁移操作
Section titled “常见迁移操作”create_table(name, options):创建新表。drop_table(name):删除表。rename_table(old_name, new_name):重命名表。add_column(table_name, column_name, type, options):向表中添加新列。rename_column(table_name, old_column_name, new_column_name):重命名现有列。change_column(table_name, column_name, type, options):更改列的类型或选项。remove_column(table_name, column_name, options):删除列。add_index(table_name, column_name_or_columns, options):向一个或多个列添加索引。remove_index(table_name, options_or_column_name):删除索引。add_reference(table_name, ref_name, options)或add_belongs_to:添加外键引用。t.timestamps:在create_table块内的一个辅助方法,添加created_at和updated_at列。
迁移中支持的数据类型:
- :string(用于短文本,例如标题)
- :text(用于长文本,例如描述)
- :integer(用于整数)
- :bigint(用于更大的整数)
- :float(用于浮点数)
- :decimal(用于精确的小数,常用于货币)
- :datetime(用于日期和时间)
- :timestamp(类似于 datetime)
- :date(仅用于日期)
- :time(仅用于时间)
- :binary(用于二进制数据)
- :boolean(用于布尔值 true/false)
常见列选项::limit, :precision, :scale(用于 decimals),:default, :null(布尔值),:index(布尔值或选项哈希)。
您可以使用 rails generate migration 命令生成迁移文件。Rails 在文件名中使用时间戳来确保迁移按顺序运行。
示例:为我们的 books 和 subjects 表生成迁移(如果尚未通过 rails g model 生成):
$ bin/rails generate migration CreateBooks title:string price:decimal:10,2 subject_id:bigint:index description:text published_at:date$ bin/rails generate migration CreateSubjects name:string:uniq这会创建类似 db/migrate/YYYYMMDDHHMMSS_create_books.rb 和 db/migrate/YYYYMMDDHHMMSS_create_subjects.rb 的文件。
如果您使用 rails generate model Book title:string ...,迁移会自动创建。上面的示例展示了如何独立创建迁移。请注意 :index 会在 subject_id 上创建索引,:uniq 会在 subjects 表的 name 列上创建唯一索引。
编辑迁移文件
Section titled “编辑迁移文件”让我们看看一个生成的(或手动创建的)迁移文件的内容。对于 CreateBooks:
class CreateBooks < ActiveRecord::Migration[7.0] # 使用您当前的 Rails 版本 def change create_table :books do |t| t.string :title, null: false t.decimal :price, precision: 10, scale: 2 # t.references :subject, null: false, foreign_key: true # 添加外键的推荐方式 t.bigint :subject_id # 如果不使用 t.references t.text :description t.date :published_at
t.timestamps # 添加 created_at 和 updated_at 列 end # 如果不使用带有 index: true 的 t.references,或者 subject_id 是手动添加的,则单独添加索引 add_index :books, :subject_id unless index_exists?(:books, :subject_id) add_index :books, :title # 示例:在 title 列上添加索引 endend对于 CreateSubjects:
class CreateSubjects < ActiveRecord::Migration[7.0] def change create_table :subjects do |t| t.string :name, null: false
t.timestamps end add_index :subjects, :name, unique: true unless index_exists?(:subjects, :name, unique: true) endendActiveRecord::Migration[7.0]指定了此迁移是为哪个 Rails 版本编写的。change方法用于 Active Record 知道如何自动回滚的迁移(例如,create_table可以通过drop_table回滚)。- 对于不可回滚的变更,您需要定义单独的
up(应用变更)和down(回滚变更)方法。 t.timestamps是一个辅助方法,添加created_at和updated_at列,Active Record 会自动管理它们。null: false使该列在数据库层面成为必需项。t.references :subject, foreign_key: true是一种便捷方式,用于添加subject_id列,并在其上添加索引和外键约束。
重要:避免将数据填充(例如 Subject.create(...))放在迁移文件中。迁移用于模式变更。数据填充应放在 db/seeds.rb 或自定义 Rake 任务中。
要将待处理的迁移应用到您的开发数据库:
$ bin/rails db:migrateRails 会在 schema_migrations 表中跟踪哪些迁移已经运行。此命令只会运行尚未运行的迁移。
其他有用的迁移命令:
bin/rails db:rollback:回滚上一次迁移。bin/rails db:rollback STEP=3:回滚最近 3 次迁移。bin/rails db:migrate:status:显示所有迁移的状态(已运行或未运行)。bin/rails db:migrate VERSION=YYYYMMDDHHMMSS:向上或向下迁移到指定版本。bin/rails db:schema:load:从db/schema.rb加载模式到当前环境的数据库(破坏性操作,会丢弃现有表)。对于快速设置新数据库非常有用。bin/rails db:seed:运行db/seeds.rb文件。
为不同环境运行迁移
Section titled “为不同环境运行迁移”要为特定环境(例如生产环境)运行迁移,请设置 RAILS_ENV 环境变量:
$ RAILS_ENV=production bin/rails db:migrate接下来做什么?
Section titled “接下来做什么?”在定义并迁移了数据库模式之后,您现在可以专注于构建控制器和视图,让用户与应用程序的数据进行交互了。