Rails迁移高级 #

一、可逆迁移 #

1.1 reversible方法 #

ruby
class ReversibleMigration < ActiveRecord::Migration[7.1]
  def change
    reversible do |dir|
      dir.up do
        # 向上迁移时执行
        execute "CREATE EXTENSION IF NOT EXISTS hstore"
      end
      
      dir.down do
        # 向下迁移时执行
        execute "DROP EXTENSION IF EXISTS hstore"
      end
    end
  end
end

1.2 up和down方法 #

ruby
class UpDownMigration < ActiveRecord::Migration[7.1]
  def up
    create_table :articles do |t|
      t.string :title
      t.text :body
    end
    
    execute "CREATE INDEX CONCURRENTLY idx_articles_title ON articles(title)"
  end
  
  def down
    execute "DROP INDEX CONCURRENTLY idx_articles_title"
    drop_table :articles
  end
end

二、数据迁移 #

2.1 迁移中处理数据 #

ruby
class PopulateArticleStatus < ActiveRecord::Migration[7.1]
  def up
    Article.reset_column_information
    Article.find_each do |article|
      article.update(status: 'published') if article.published_at?
    end
  end
  
  def down
    Article.reset_column_information
    Article.update_all(status: nil)
  end
end

2.2 批量处理 #

ruby
class BulkUpdateArticles < ActiveRecord::Migration[7.1]
  def up
    Article.in_batches do |relation|
      relation.update_all(status: 'draft')
      sleep(0.1)  # 避免数据库压力过大
    end
  end
end

三、安全迁移 #

3.1 安全添加索引 #

ruby
class SafeAddIndex < ActiveRecord::Migration[7.1]
  disable_ddl_transaction!

  def change
    add_index :articles, :title, algorithm: :concurrently
  end
end

3.2 安全添加外键 #

ruby
class SafeAddForeignKey < ActiveRecord::Migration[7.1]
  def change
    add_foreign_key :articles, :users, validate: false
    
    # 在单独迁移中验证
    # validate_foreign_key :articles, :users
  end
end

四、总结 #

4.1 核心要点 #

要点 说明
reversible 可逆迁移
up/down 明确上下迁移
数据迁移 批量处理数据
安全迁移 并发索引、延迟验证

4.2 下一步 #

现在你已经掌握了迁移高级特性,接下来让我们学习 数据填充,深入了解Rails的数据填充系统!

最后更新:2026-03-28