开源项目 Rails migration 文件也应该按模块存放

swordray · 2014年06月18日 · 最后由 swordray 回复于 2014年07月03日 · 3338 次阅读

Rails migration 所有文件都放在 db/migrate 目录。这对于简洁的项目来说是极好的,但对于大型的模块化的项目就不是那么理想,例如我目前参与的项目已有近千个迁移文件,查看极为不便。

既然 MVC 可以是模块化的,migration 也理应同样如此,为此我们发布了开源项目 modular_migration

在 Gemfile 中引用 gem

gem 'modular_migration'

照常使用 Rails 生成器

$ rails generate model Core::User name:string
    invoke  active_record
    create    app/models/core/user.rb
    create    app/models/core.rb
    create    db/migrate/core/user/20140324105328_create_core_users.rb

效果如下:

不同模块的 migration 存放整洁有序,可以单独查看每个 model 的迁移文件,令项目更清晰。

地址:https://github.com/swordray/modular_migration 欢迎 star, fork, pull request ^_^

感谢主要作者 @mystery from 优众网

好东西,不过没看懂大体是如何工作的,还请完善一下 Readme,或者建个 Wiki。

一般不是会清理掉很久的 migration 嘛 有最终版的 schema 就足够了

#1 楼 @ugoa https://github.com/swordray/modular_migration 如文档所说,只需要在 Gemfile 里引用即可,不用额外操作

项目到一个节点后如某个版本后,用最新的 schema.rb 作为一个新的 migration,删掉旧的 migrations 就可以了。

当还有一堆 migrations 还在维护的时候,这个 gem 看起来很清爽。每个 model 的演化进程都很清楚。

但是有几个问题:

  1. rollback 和 migrate 能否正常运行?这里没有测试来保证。

  2. 按时间戳的维护变困难了。就像@leozwa@rainchen 说的,定期清理完全不需要的 migrations 也是 Rails good practices 之一。但现在 migration 不按时间排列,很难决定哪一截是需要和不需要的。

我提供两个思路来解决#2

思路一:提供一个 rake task 来按时间戳排列。但文件多可能很耗时间,且看不到文件细节。

思路二:完全放弃这个 gem 而采取一种新的思路。 这个 gem 的是按 model 或 namespace 查看。那么,直接做一个 rake task 是不是也能达到同样目的呢?

比如这些假想的 tasks:

rake migration list Post 这个就会列出所有 posts table migrations 文件。

rake migration view Post 这个就把所有 posts migrations 输出到 stdout 来观看。

这样的话,migration 还是不动,但多了些手段来方便查看,达到类似这个 gem 的目的。

确实需要这么个功能

好多好多的书啊 😄

当项目到达某个结点之后,就对 migrations 打包一次即可。如果你说我需要 rollback 怎么办,我认为没机会存在这种情况,因为你已经有了上千个 migrations,你说我要回滚到第 500 个 migrations 去,这绝对体现了你们的产品经理和技术总监的能力是多么得糟糕!万一真有这种情况,也绝对是继续写代码,将逻辑和数据回迁到之前去。

对于用文件夹这种结构化的文件存放,本身 rails 就支持,而我认为这个也并不是很需要,就算是大型的项目。

通常项目有大版本更新后,并且到了稳定状态,就可以对迁移文件进行打包了,可以不全部打包,保留 1 个月或者两个月内的迁移文件就可以了。

#5 楼 @billy

这个 gem 已经经过测试,并且在我们项目的正式环境里使用了数月时间,没有出现问题,反馈不错

#2 楼 @leozwa #4 楼 @rainchen #5 楼 @billy #8 楼 @hz_qiuyuanxin

保留 migration 的记录不是更好么,可以追溯一个 model 的变动情况,保留每位工程师贡献的代码

#10 楼 @swordray 我觉得追溯一个 table 的变化情况实在没啥必要... 有些已经不再需要的 column 记录下来没意义 而且难免会出现加上了某些 column 后又删除改动的 中间的一些状态完全没啥保留价值可言

#10 楼 @swordray 不过还是看团队需要吧 也许只是我没遇到过需要回查 migration files 的需求 😆

对于大的分模块的项目,进行 migration 文件归类管理确实很有必要。不过对中小型项目而言这种目录结构太复杂了。

我以前也喜欢删旧的 migration,尤其是加了字段然后又删了的情况。后来觉得这样挺折腾的,还要去服务器上删除 scheme_migrations 里面的记录,要是有 staging, production 等多个服务器还要麻烦,只是心里觉得干净了一些。现在的项目试着完全没有管旧的 migration,任何一个小的修改都开 migration 去做,感觉维护还更方便了,什么都不用操心。

BTW,自从换了 Sublime Text 之后,我发现多了一个看 migration 的方法,直接用 cmd+p 模糊匹配 migration 文件,只要文件名遵从一定的规律,查找起来也挺方便,加上切换文件即时预览,也够用了。

#10 楼 @swordray

保留 migration 的记录不是更好么,可以追溯一个 model 的变动情况,保留每位工程师贡献的代码

git 不就是做这种事情么?

#12 楼 @leozwa 我经常做 code review,所以有这种情况

#14 楼 @hz_qiuyuanxin 上万次的 commit 记录查看起来不太容易,所以我会尽量把代码留在当前分支

#16 楼 @swordray git 很强大的!

另外 code review 现在可以用 gitlab

楼主可以尝试 pr 一下 rails 嘛

哎 我觉得楼主真幸福。。我们最核心的数据库是用 SQL 直接管理的 根本没有形成像 migration 这么好的机制 几乎不可能重新复刻一个干净的仅包含最基本数据的数据库

#19 楼 @huobazi 这个建议不错,多谢!

#20 楼 @iBachue 可以考虑把某一时间的数据库结构用 rake db:schema:dump 导出,之后新的修改再用 migration 维护

#22 楼 @swordray DBA 不会同意的

#23 楼 @iBachue 不知道是否可以开发者本地用 migration,正式环境更新的时候再给 DBA“翻译”成 SQL

#24 楼 @swordray 那 QA 环境用哪个呢?

#25 楼 @iBachue 你们 QA 环境是谁维护呢?自己维护就可以用 migration

#26 楼 @swordray 顾名思义 QA 环境 QA Own

QA Own 就没办法了

#28 楼 @swordray 好东西,有用!迁移文件上 100,就管不过来了

感谢主要作者 @mystery from 优众网

需要 登录 后方可回复, 如果你还没有账号请 注册新账号