Rails:'schema.rb'中的版本号是用于什么的吗?

时间:2010-06-05 03:44:28

标签: ruby-on-rails database migration

现在Rails已经timestamped migrations/db/schema.rb顶部的单个版本号似乎毫无意义。在处理多个开发人员或多个分支时,有时版本号最终不正确。

Rails是否甚至再使用:version参数了?

它是否有任何不正确之处(例如:它不反映最近应用的提交的时间戳)?

示例:

ActiveRecord::Schema.define(:version => 20100417022947) do
  # schema definition ...
end

2 个答案:

答案 0 :(得分:31)

实际上,版本比这更重要。您引用的代码实际上只是assume_migrated_upto_version所做的一小部分。迁移版本的真正效果是,以前的所有迁移 (在db / migrate目录中找到) 被认为已经运行。 (所以是的,它完成了函数名称的建议。)

这有一些有趣的含义,特别是在多人同时提交新迁移的情况下。

如果您对schema.rb进行版本控制,这是Rails团队推荐的那样,那么你没问题。您100%保证有冲突(架构版本),并且提交/合并用户必须通过合并其更改并将:version设置为两者中的最高版本来解决它。希望他们能正确合并。

有些项目选择通过保持schema.rb不受版本控制来避免这种持续的冲突问题。它们可能仅依赖于迁移,或者保留其偶尔更新的模式的单独版本控制副本。

如果某人创建了一个时间戳之前到您的schema.rb:version的迁移,则会出现此问题。如果您使用db:migrate,您将应用他们的迁移,您的schema.rb将被更新(但保留相同,更高版本),一切都很好。但是如果你碰巧遇到db:schema:load(或db:reset),你不仅会错过他们的迁移,而且 assume_migrated_upto_version会将他们的迁移标记为已经应用。

此时最佳解决方案可能是要求用户将其迁移时间戳重新加入合并时间。

理想情况下,我更喜欢schema.rb实际上是否包含已应用的迁移数列表,而不是假定为up-here:版本。但我怀疑这会发生--Rails团队似乎相信通过检查schema.rb文件可以充分解决问题。

答案 1 :(得分:5)

我决定调查自己。事实证明,由于带时间戳的迁移,唯一的东西 Rails确实使用该数字假设已经应用了具有该特定时间戳的迁移,因此创建了适当的schema_migration表中的条目(如果它不存在)。

来自:/lib/active_record/connection_adapters/abstract/schema_statements.rb

def assume_migrated_upto_version(version, migrations_path = ActiveRecord::Migrator.migrations_path)
    # other code ... 
    unless migrated.include?(version)
      execute "INSERT INTO #{sm_table} (version) VALUES ('#{version}')"
    end
    # ...