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

发布于 2024-09-26 14:28:48 字数 174 浏览 1 评论 0原文

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

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

这样,我同事的迁移将位于我项目的 db/migrate/other_db 文件夹中。

如何配置 Rails 迁移以在这个额外文件夹中运行迁移?

A colleague and I are working in different projects that share some models. So, we are sharing the models through a git submodule.

Additionally, we'd like to be able to also share migrations:

In this way, my colleague's migrations would be in the folder db/migrate/other_db of my project.

How can I configure rails migrations to also run the migrations in this extra folder?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

债姬 2024-10-03 14:28:48

在您的配置文件(所有环境的 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"],

In your config file (config/application.rb for all environments or config/environments/$(environment).rb only for particular environment) add this line:

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

And if you want to change default 'db/migrate' path (config.paths['db/migrate'] is an array with one string 'db/migrate' by default), do this:

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

Here are default config.paths, which we also can change:

"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"],
残龙傲雪 2024-10-03 14:28:48

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 中弃用。

Update for Rails 5/6;

Rails 5 recommends setting additional migration paths in your config/database.yml file. It's very easy, see this example;

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

ActiveRecord::Migrator.migrations_path= will be deprecated in Rails 6.

倒带 2024-10-03 14:28:48

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

based on the answer by Swanand, we can write a migration to load the migrations in an external dir:

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
烏雲後面有陽光 2024-10-03 14:28:48

我不知道有一种非常干净的方法来做到这一点,但是运行迁移的代码看起来像:

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

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

I do not know of a very clean way to do it, but the code that runs migrations looks something like:

@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 

Where,

@migrations_path = 'db/migrate'

So if you change this to read from config file instead, it may work out in your favour. But as I said, this is definitely not a very clean way to do it.

娇妻 2024-10-03 14:28:48

顺便说一句,如果您正在构建一个与 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 文件中使用类似这样的东西。

By the way, if you are building a gem to work with Rails, you can place a block like the following in your rail tie to add the gem's own migrations.

  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

There is no need to copy migrations from your gem with generators if you use this technique.

You can make a method to yield the root directory of your gem with some thing like this...

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

  module_method :root
end

... in the file lib/my_gem_name.rb in your gem.

荒人说梦 2024-10-03 14:28:48

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

Just add this initializer to your 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
漫漫岁月 2024-10-03 14:28:48

我正在使用 Rails 5.2 和引擎(及其迁移),在这种情况下,我发现我的解决方案效果最好,因为推荐的解决方案将迁移路径添加到 config/database.yml 文件不起作用。毕竟,该文件通常会被版本控制 (git) 忽略。

我的解决方案是将其添加到 lib/engine.rb 文件中:

# This is required to use this engine migrations in the main Rails application
initializer 'append_migrations' do |app|
  unless app.root.to_s.match?(root.to_s)
    config.paths['db/migrate'].expanded.each do |expanded_path|
      # To allow `rails db:migrate` to work
      app.config.paths['db/migrate'] << expanded_path
      # To allow the local development server to check if there are pending migrations
      ActiveRecord::Migrator.migrations_paths << expanded_path
    end
  end
end

I'm using Rails 5.2 with an engine (with its migrations) and in this context, I find that my solution works best because the recommended solution to add the migration paths to the config/database.yml file doesn't work. After all, that file is usually ignored by the version control (git).

My solution is to add this to the lib/engine.rb file:

# This is required to use this engine migrations in the main Rails application
initializer 'append_migrations' do |app|
  unless app.root.to_s.match?(root.to_s)
    config.paths['db/migrate'].expanded.each do |expanded_path|
      # To allow `rails db:migrate` to work
      app.config.paths['db/migrate'] << expanded_path
      # To allow the local development server to check if there are pending migrations
      ActiveRecord::Migrator.migrations_paths << expanded_path
    end
  end
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文