如果最新的迁移是相同的,Rails如何知道还有待处理的迁移?

时间:2018-10-07 18:51:20

标签: ruby-on-rails

鉴于我在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表中不存在某些较旧的迁移?

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

2 个答案:

答案 0 :(得分: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表中减去了所有版本。

答案 1 :(得分:0)

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

schema.rb的内容是从数据库而不是迁移生成的,因此,如果您进行了一些迁移,则创建其他表/列并删除了这些迁移,如果您运行完整的{ {1}}。