如何配置额外/不同的迁移文件夹

我和一位同事正在分享一些模型的不同项目。 所以,我们通过git子模块共享模型。

此外,我们希望能够共享迁移:

通过这种方式,我的同事的迁移将位于我的项目的db/migrate/other_db文件夹中。

如何配置rails迁移以在此额外文件夹中运行迁移?

在您的配置文件(所有环境的config / application.rb或仅适用于特定环境的config / environments / $(environment).rb)中添加以下行:

 config.paths['db/migrate'] += 'db/migrate/other_db' 

如果你想更改默认的’db / migrate’路径(config.paths [‘db / migrate’]是一个默认包含一个字符串’db / migrate’的数组),请执行以下操作:

 config.paths['db/migrate'] = ['db/my_migrate'] 

这是默认的config.paths,我们也可以更改:

 "app" => ["app"], "app/assets" => ["app/assets"], "app/controllers" => ["app/controllers"], "app/helpers" => ["app/helpers"], "app/models" => ["app/models"], "app/mailers" => ["app/mailers"], "app/views" => ["app/views"], "lib" => ["lib"], "lib/assets" => ["lib/assets"], "lib/tasks" => ["lib/tasks"], "config" => ["config"], "config/environments" => ["config/environments"], "config/initializers" => ["config/initializers"], "config/locales" => ["config/locales"], "config/routes" => ["config/routes.rb"], "db" => ["db"], "db/migrate" => ["db/migrate"], "db/seeds" => ["db/seeds.rb"], "vendor" => ["vendor"], "vendor/assets" => ["vendor/assets"], "vendor/plugins" => ["vendor/plugins"], "config/database" => ["config/database.yml"], "config/environment" => ["config/environment.rb"], "lib/templates" => ["lib/templates"], "log" => ["log/development.log"], "public" => ["public"], "public/javascripts" => ["public/javascripts"], "public/stylesheets" => ["public/stylesheets"], "tmp" => ["tmp"], 

根据Swanand的回答,我们可以编写一个迁移来加载外部目录中的迁移:

 class MigrateMetadata < ActiveRecord::Migration MIGRATIONS_PATH='db/migrate/metadata' def self.up Dir["#{MIGRATIONS_PATH}/[0-9]*_*.rb"]. sort.map{|filename|require filename}.flatten. each{|class_name| const_get(class_name).up} end def self.down Dir["#{MIGRATIONS_PATH}/[0-9]*_*.rb"].sort.reverse. map{|filename|require filename}.flatten. each{|class_name| const_get(class_name).down} end end 

我不知道一个非常干净的方法,但运行迁移的代码看起来像:

 @migrations ||= begin files = Dir["#{@migrations_path}/[0-9]*_*.rb"] migrations = files.inject([]) do |klasses, file| version, name = file.scan(/([0-9]+)_([_a-z0-9]*).rb/).first 

哪里,

 @migrations_path = 'db/migrate' 

因此,如果您将其更改为从配置文件中读取,则可能会对您有利。 但正如我所说,这绝对不是一个非常干净的方式。

顺便说一下,如果你正在构建一个使用Rails的gem,你可以在你的铁路领带中放置一个像下面这样的块来添加gem自己的迁移。

  root = ... # the path to your gem initializer :append_migrations do |app| unless app.root.to_s.match root app.config.paths["db/migrate"] << File.join(root, 'db/migrate') end end 

如果使用此技术,则无需使用生成器从gem中复制迁移。

您可以创建一个方法来生成gem的根目录,并使用这样的东西......

 module MyGemName def root File.expand_path '../..', __FILE__ end module_method :root end 

...在gem中的文件lib / my_gem_name.rb中。

只需将此初始化程序添加到lib / engine.rb:

 initializer 'your_engine_name.migrations' do |app| config.paths['db/migrate'].expanded.each do |expanded_path| app.config.paths['db/migrate'] << expanded_path ActiveRecord::Migrator.migrations_paths << expanded_path if Rake.application.top_level_tasks.empty? ActiveRecord::Migration.check_pending! if ActiveRecord::Migrator.needs_migration? end end end