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

时间:2010-10-08 07:41:04

标签: ruby-on-rails ruby directory migration

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

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

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

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

6 个答案:

答案 0 :(得分:28)

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

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

如果你想改变默认的“db / migrate' path(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"],

答案 1 :(得分:4)

根据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

答案 2 :(得分:2)

我不知道一种非常干净的方法,但运行迁移的代码类似于:

@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'

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

答案 3 :(得分:2)

顺便说一句,如果你正在构建一个使用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复制迁移。

你可以创建一个方法来生成你宝石的根目录,有这样的东西......

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

  module_method :root
end

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

答案 4 :(得分:2)

Rails 5/6更新;

Rails 5建议在config/database.yml文件中设置其他迁移路径。很简单,请参见此示例;

development:
  migrations_paths:
  - "db/migrate/other_db"
  - "db/migrate/something_else"

ActiveRecord::Migrator.migrations_path=将在Rails 6中弃用。

答案 5 :(得分:1)

只需将此初始化程序添加到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