Ruby-on-rails 我如何在带有活动记录的 Rails 中使用两个不同的数据库?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1226182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:35:36  来源:igfitidea点击:

How do i work with two different databases in rails with active records?

ruby-on-railsrubyactiverecord

提问by gustavgans

I need to use different database connections in different Rails models. Is there a not-so-hacky way to do that?

我需要在不同的 Rails 模型中使用不同的数据库连接。有没有一种不那么hacky的方法来做到这一点?

Any links or search keywords would be great :)

任何链接或搜索关键字都会很棒:)

采纳答案by nitecoder

mikej is right. I did however write a gem that makes the model code to connect a little bit cleaner, check it out.

迈克是对的。然而,我确实写了一个 gem,使模型代码连接起来更简洁,检查一下

回答by mikej

Add new sections to your database.ymle.g.

将新部分添加到您的database.yml例如

other_development:
  adapter: mysql
  database: otherdb_development
  username: root
  password:
  host: localhost

other_production:
  adapter: mysql
  database: otherdb_production
  username: root
  password:
  host: localhost

Add a class in lib/other_database.rb

添加一个班级 lib/other_database.rb

class OtherDatabase < ActiveRecord::Base
  establish_connection "other_#{RAILS_ENV}"
end

and then for each model which isn't in the default database subclass from OtherDatabasee.g.:

然后对于不在默认数据库子类中的每个模型,OtherDatabase例如:

class MyModel < OtherDatabase
   # my model code...
end

回答by penger

I have been using the following to connect to 2 db in the same app. I put them in lib folder since everything in there is loaded.

我一直在使用以下内容连接到同一个应用程序中的 2 db。我将它们放在 lib 文件夹中,因为那里的所有内容都已加载。

require 'active_record'

class OldDatabase < ActiveRecord::Base
  self.abstract_class = true
  establish_connection(
  :adapter  => 'mysql',
  :database => 'weather',
  :host     => 'localhost',
  :username => 'root',
  :password => 'password'
  )
end

class NewDatabase < ActiveRecord::Base
  self.abstract_class = true
  establish_connection(
  :adapter  => 'mysql',
  :database => 'redmine',
  :host     => 'localhost',
  :username => 'root',
  :password => 'password'
  )
end

class WeatherData < OldDatabase
end

class Board < NewDatabase
end

Hope that helps

希望有帮助

回答by penkovsky

Update for Rails 3.x:

Rails 3.x 的更新:

class MyModel < ActiveRecord::Base
  establish_connection "other_#{Rails.env}"
end

回答by Adi

I think that the prettiest way to connect to another database with active model is creating base class for external database, and then inherite from that base in your model. This method works fine with rails 4.2.6 and 5.0.4

我认为使用活动模型连接到另一个数据库的最漂亮方法是为外部数据库创建基类,然后在模型中从该基类继承。此方法适用于 rails 4.2.6 和 5.0.4

For example:

例如:

# in /models/external_db/base.rb
require 'active_record'

class ExternalDb::Base < ActiveRecord::Base
  self.abstract_class = true
  establish_connection "external_db_#{Rails.env}".to_sym
end

And in your model class:

在您的模型类中:

# in /models/external_db/some_model.rb
class ExternalDB::SomeModel < ExternalDb::Base
  # your code
end

But you must define external database in /config/database.yml

但是你必须在 /config/database.yml 中定义外部数据库

# in /config/database.yml
external_db_development:
  adapter: sqlite3
  pool: 5
  timeout: 5000
  database: db/external_db_development.db

external_db_production:
  adapter: sqlite3
  pool: 5
  timeout: 5000
  database: db/external_db_production.db

回答by thisismydesign

Rails 6 added native support for multiple databases: https://edgeguides.rubyonrails.org/active_record_multiple_databases.html

Rails 6 添加了对多个数据库的原生支持:https: //edgeguides.rubyonrails.org/active_record_multiple_databases.html

database.yml

database.yml

development:
  one:
    <<: *default
  other:
    <<: *default

Model base classes:

模型基类:

class OneModelBase < ActiveRecord::Base
  around_action :set_db

  private

  def set_db
    ActiveRecord::Base.connected_to(database: :one) do
      yield
    end
  end
end

class OtherModelBase < ActiveRecord::Base
  around_action :set_db

  private

  def set_db
    ActiveRecord::Base.connected_to(database: :other) do
      yield
    end
  end
end

You'll also have different migrations and schemas per DB. Running a command like rails db:createwill create all databases. You can scope commands, e.g. rails db:create:other.

您还将为每个 DB 提供不同的迁移和架构。运行像这样的命令rails db:create将创建所有数据库。您可以作用域命令,例如rails db:create:other.

回答by Vasfed

In rails 4.1+ establish_connectionnow takes a symbol:

在 rails 4.1+ 中,establish_connection现在需要一个符号:

class OtherDbModel < ActiveRecord::Base
  establish_connection :"other_#{Rails.env}"
end