代码之家  ›  专栏  ›  技术社区  ›  Daniel Beardsley

rails:“schema.rb”中的版本号是否用于任何用途?

  •  22
  • Daniel Beardsley  · 技术社区  · 15 年前

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

    铁轨也用那个吗 :version 参数了吗?

    错误是否有任何危害(如:它不反映最近应用的提交的时间戳)?

    例子:

    ActiveRecord::Schema.define(:version => 20100417022947) do
      # schema definition ...
    end
    
    2 回复  |  直到 15 年前
        1
  •  30
  •   Adrian Irving-Beer    14 年前

    实际上,版本比这个重要得多。您所引用的代码实际上只是假设“迁移到”版本的代码的一小部分。迁移版本的真正效果是 所有以前的迁移 (在db/migrate目录中找到) 假定已运行。 (所以是的,它按照函数名的建议执行。)

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

    如果您的schema.rb版本是Rails团队推荐的,那么您就没事了。您100%保证有冲突(模式版本),提交/合并用户必须通过合并他们的更改并将:版本设置为两者中的最高版本来解决冲突。希望他们能正确合并。

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

    如果有人使用时间戳创建迁移,则会出现问题。 先前的 到您的模式。rb的:版本。如果您db:migrate,您将应用它们的迁移,您的schema.rb将被更新(但保留相同的更高版本),并且一切都很好。但是,如果您应该改为使用db:schema:load(或db:reset),那么不仅会丢失它们的迁移,而且 假设已迁移的版本将标记其迁移为已应用。

    此时最好的解决方案可能是要求用户在迁移到合并时重新标记迁移时间。

    理想情况下,我希望schema.rb实际上包含一个应用的迁移编号列表,而不是这里的假设:version。但我怀疑这是否会发生——Rails团队似乎认为通过签入schema.rb文件可以充分解决这个问题。

        2
  •  5
  •   Daniel Beardsley    15 年前

    我决定调查一下自己。事实证明,由于时间戳的迁移, 只有东西 Rails的号码是 假设已经应用了具有特定时间戳的迁移 因此,如果模式迁移表不存在,则在该表中创建适当的条目。

    来自: /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
        # ...