【问题标题】:How does Rails know there are pending migrations if latest migration is the same?如果最新的迁移相同,Rails 如何知道有待处理的迁移?
【发布时间】:2019-03-12 12:07:45
【问题描述】:

鉴于我在 schema_migrations 表中有以下版本:

| 20180822231257 |
| 20180822234804 |
| 20180829011800 |
| 20180924212812 |

鉴于我使用以下迁移检查了我的项目的特定分支(下面我省略了 db/migrate/*.rb 文件的完整文件名):

| 20180822231257 |
| 20180822234804 |

20180827225521
20180828172831

| 20180829011800 |

20180911233144
20180913172923

| 20180924212812 |

如您所见,没有管道的文件代表我的 db/migrate 文件夹中的文件,这些文件不在数据库的 schema_migrations 文件中。

现在当我尝试运行 rails 时,我收到以下错误:

Migrations are pending. To resolve this issue, run:
bin/rake db:migrate RAILS_ENV=development

当我查看 schema.rb 时,我注意到了这一行:

ActiveRecord::Schema.define(version: 20180924212812) do

如您所见,schema.rb 指向的是最新版本。

但是,schema.rb 包含一些不在我拥有的数据库中的代码,例如用于那些不在数据库中的迁移之一的 create_table 语句:

  create_table "some_table", force: :cascade do |t|
    t.integer  "some_id",      limit: 4
    t.integer  "default_view", limit: 4
    t.datetime "created_at",             null: false
    t.datetime "updated_at",             null: false
  end

尽管最新的迁移版本是相同的,Rails 是否检测到当前 schema_migrations 表中不存在一些较旧的迁移?

(顺便说一句,我认为两个分支具有相同最新提交的原因是因为我认为有人将特定迁移挑选到另一个分支而不是其他迁移)。

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    here

    def needs_migration?
      (migrations.collect(&:version) - get_all_versions).size > 0
    end
    
    def migrations
      migrations = migration_files.map do |file|
        version, name, scope = parse_migration_filename(file)
        raise IllegalMigrationNameError.new(file) unless version
        version = version.to_i
        name = name.camelize
    
        MigrationProxy.new(name, version, file, scope)
      end
    
      migrations.sort_by(&:version)
    end
    def migration_files
      paths = Array(migrations_paths)
      Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
    end
    

    您可以看到 rails 获取了 db/migrate 中的所有文件,并从中减去了 SchemaMigration 表中的所有版本。

    【讨论】:

      【解决方案2】:

      Rails 创建一个schema_migrations 表,它会在其中插入所有已成功运行的迁移。如果您的环境配置为检查是否已运行所有迁移,它会将您的db/migrate 目录中的所有迁移与schema_migrations 表中的所有versions 进行比较。

      schema.rb 的内容是从您的数据库生成的,而不是迁移,因此如果您有一些迁移创建额外的表/列并删除了这些迁移,那么您的架构将包含如果您运行完整的rake db:migrate:reset 将不存在的表.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-16
        • 1970-01-01
        • 2016-12-08
        • 2020-10-30
        • 1970-01-01
        • 1970-01-01
        • 2017-03-27
        相关资源
        最近更新 更多