鉴于我在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表中不存在某些较旧的迁移?
(作为一个旁注,我认为两个分支具有相同的最新提交的原因是因为我认为有人挑选了特定的迁移到另一个分支,而不是其他迁移)。
答案 0 :(得分:1)
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}}。