You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 7数据库迁移测试:替代弃用方法及示例

Rails 7 数据库迁移测试:替代弃用方法及实战示例

弃用方法的替代方案

Rails 7 中已弃用 ActiveRecord::Migrator.new,官方推荐使用 ActiveRecord::MigrationContext 来执行迁移操作,它是 Rails 6+ 引入的迁移管理工具,完全适配 Rails 7。

核心测试思路

针对包含表重命名、字段增删、数据迁移及关联更新的场景,测试流程固定为:

  1. 重置数据库到目标迁移的前一个版本,模拟迁移前状态
  2. 创建符合迁移前结构的测试数据
  3. 执行目标迁移
  4. 验证迁移后的表结构、数据内容、关联关系是否符合预期

超简单实战示例

假设我们有这样一个迁移:

  • 将 old_posts 表重命名为 articles
  • 删除 old_posts 的 old_content 字段,新增 body 字段,并用 old_content 的值填充 body
  • 更新 comments 表的关联:将外键从 old_post_id 改为 article_id

测试文件(test/migrations/rename_old_posts_to_articles_test.rb)

require "test_helper"

class RenameOldPostsToArticlesTest < ActiveSupport::TestCase
  setup do
    # 目标迁移的版本号(从迁移文件名中获取,比如 20240520123456_rename_old_posts_to_articles.rb)
    @target_version = 20240520123456
    # 回滚到迁移前的版本
    migration_context = ActiveRecord::MigrationContext.new("db/migrate/", ActiveRecord::SchemaMigration)
    migration_context.migrate(@target_version - 1)

    # 创建迁移前的测试数据
    old_post = OldPost.create!(title: "测试文章", old_content: "原始内容")
    Comment.create!(old_post_id: old_post.id, text: "写得不错!")
  end

  teardown do
    # 测试结束后恢复到最新迁移版本,避免影响其他测试
    migration_context = ActiveRecord::MigrationContext.new("db/migrate/", ActiveRecord::SchemaMigration)
    migration_context.migrate(:latest)
  end

  test "迁移完成后表结构、数据及关联均符合预期" do
    # 找到目标迁移文件
    migration_context = ActiveRecord::MigrationContext.new("db/migrate/", ActiveRecord::SchemaMigration)
    target_migration = migration_context.migrations.detect { |m| m.version == @target_version }

    # 执行迁移
    target_migration.migrate(:up)

    # 1. 验证表重命名
    assert_not ActiveRecord::Base.connection.table_exists?(:old_posts), "旧表未被删除"
    assert ActiveRecord::Base.connection.table_exists?(:articles), "新表未创建"

    # 2. 验证字段与数据迁移
    article = Article.find_by(title: "测试文章")
    assert_equal "原始内容", article.body, "新字段未正确填充旧数据"
    assert_not ActiveRecord::Base.connection.column_exists?(:articles, :old_content), "旧字段未被删除"

    # 3. 验证关联更新
    comment = Comment.first
    assert_equal article.id, comment.article_id, "外键未更新"
    assert_not ActiveRecord::Base.connection.column_exists?(:comments, :old_post_id), "旧外键字段未被删除"
    assert_equal article, comment.article, "模型关联失效"
  end
end

关键说明

  • ActiveRecord::MigrationContext.new 接收两个参数:迁移文件目录(默认db/migrate/)和迁移版本记录表(ActiveRecord::SchemaMigration)
  • 测试前后通过 migrate 方法切换数据库版本,确保测试环境隔离
  • 用 table_exists? 和 column_exists? 验证结构变更,直接查询数据验证迁移正确性

内容的提问来源于stack exchange,提问作者kujosHeist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 21:08:30