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 优众网
#1 楼 @ugoa https://github.com/swordray/modular_migration 如文档所说,只需要在 Gemfile 里引用即可,不用额外操作
当还有一堆 migrations 还在维护的时候,这个 gem 看起来很清爽。每个 model 的演化进程都很清楚。
但是有几个问题:
rollback 和 migrate 能否正常运行?这里没有测试来保证。
按时间戳的维护变困难了。就像@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 个月或者两个月内的迁移文件就可以了。
对于大的分模块的项目,进行 migration 文件归类管理确实很有必要。不过对中小型项目而言这种目录结构太复杂了。
我以前也喜欢删旧的 migration,尤其是加了字段然后又删了的情况。后来觉得这样挺折腾的,还要去服务器上删除 scheme_migrations 里面的记录,要是有 staging, production 等多个服务器还要麻烦,只是心里觉得干净了一些。现在的项目试着完全没有管旧的 migration,任何一个小的修改都开 migration 去做,感觉维护还更方便了,什么都不用操心。
BTW,自从换了 Sublime Text 之后,我发现多了一个看 migration 的方法,直接用 cmd+p 模糊匹配 migration 文件,只要文件名遵从一定的规律,查找起来也挺方便,加上切换文件即时预览,也够用了。
哎 我觉得楼主真幸福。。我们最核心的数据库是用 SQL 直接管理的 根本没有形成像 migration 这么好的机制 几乎不可能重新复刻一个干净的仅包含最基本数据的数据库