• 空库执行下migrate,然后把schema.rb覆盖到最后一个version中,然后把其他的migrate删掉,这样就合并了,还是比较轻松的😀

  • 我现在有个观点: 1:要保证migrate的连续性,保证其可以顺序执行。2:定期或者大版本更新后,清理一次migrate文件目录,将多个migrate文件合并到一个,为migrate文件夹瘦身(需要注意不能创建新的migrate,而是用老的已有的version,否则会视为新的migrate而清表重建)。 这样是不是一种更好的代码维护方式?

  • schema文件会在rails db:migrate后重写的。只要不基于master执行rails db:schema:load那么master滞后的问题可以忽略。既然你们团队对schema.rb文件也不重视,很多人为了避免冲突而选择不提交它,那么变成一个团队内的约定,都不提交,也未尝不可。你单独为了一个老旧的约定,而做一些对团队其他人意义不大的事情,我觉得没必要~

  • 为什么需要手动维护这个文件?

  • 是的,重跑下就解决了。有一个场景:我们借助coding.net,多人提交合并请求,都携带了schema.rb,那么前一个合并后,后面的全部都会提示合并冲突。另外多人协作,大多数情况下,我不需要关心别人的schema改动,那么这种冲突解决就对我们来说浪费时间。

  • 谢谢,这样优缺点已经很明确了。希望这个也能给别的愿意思考与质疑的人一些参考。

  • 看productimage的模型,不应该是复数的images吗?

  • 谢谢提醒。重新认识了下,我是有了答案,希望找到一个有说服力的反方观点,感觉还是没找到~

  • 找到了一些额外的文章:

    我再重新梳理下我的思考:

    • schema.rb是一个自动生成的文件,rails db:migrate等命名执行后,此文件会重新生成。
    • schema.rb表述本地当前的数据库结构,migration外手动修改数据库后,执行rails db:migrate会反应到schema.rb上
    • schema.rb究竟应该被谁版本控制?我的观点是migrate文件,而不是版本控制工具。只有migrate文件才能表述程序的迭代。上面提到的那个点,很容易破坏schema.rb,信任这样的schema.rb然后向下迭代是危险的。而空库migrate后的schema才是唯一表述迭代后数据库该有的结构。
    • 大多观点在2011年就已经加入,schema.rb中的注释是07年加入的。我不认为在当前的计算机配置下,rails db:migrate会比'rails db:schema:load慢多少,所以我不认为这一点它可以快速迁移数据库到你期望的状态` 还依然会是优点。另外rails项目一般也不庞大~
    • 多人协作时,大部分都负责不同的模块,同时修改某个表导致的冲突不多。git的不智能,导致的version冲突的问题,让其发生并且去花费时间解决,并没有意义。
    • 合并到主分支,一定是顺序执行的。假如同时修改一个表,那么最后一个提交到主分支的人在提交前就应该发现到了migrate冲突并解决。理论上存在可能性,同时删除了一个字段,但是概率很低。并且现在的开发理念中,都会有各种测试手段与流程。取舍之间,我选择舍弃会造成冲突的schema.rb跟踪,换来存在小概率migrate定义冲突情况的发生,并通过测试等手段解决掉这个副作用问题。
    • 它加入到版本控制确实也不会对团队造成太大的生产力浪费,但是频次还是比较高的。基于上面的一些观点,我还是觉得加入到版本控制没有大的优点,那么把它移出版本跟踪,对团队还是会减少一些此文件冲突烦恼的。
    • 再次强调下,我认为schema.rb应该被migrate文件控制,而不是版本工具。
  • 我自测了一下,数据库里面直接删除一个字段,然后执行一个空的migrate,接着schema.rb会更新为当前数据库的结构。而不和migrate文件定义的一致。似乎schema.rb只是rails db:migrate执行后,rails根据数据库结构重建的结果,只反应本地数据库的状态。

    重跑 migrate 之后和线上数据库 schema 不一致的一定是手动修改过数据库,那么把schema.rb加到文件跟踪也不会根本性解决问题。因为migrate文件会影响数据库结构,除了rails db:schema:load外,schema.rb并不会反影响到数据库结构。

    如上成立的话,还是感觉schema.rb在版本跟踪中没有意义。