Как я могу динамически изменять базу данных Active Record для всех моделей в Ruby on Rails?

В нашей программе каждый клиент получает свою базу данных. Мы отправляем им по электронной почте ссылку, которая соединяет их с их базой данных. Ссылка содержит GUID, который сообщает программе, к какой базе данных подключаться.

Как динамически и программно подключить ActiveRecord к нужной базе данных?


person Tilendor    schedule 07.10.2008    source источник


Ответы (4)


Вы также можете легко сделать это без жесткого кодирования и запускать миграцию автоматически:

customer = CustomerModel.find(id)
spec = CustomerModel.configurations[RAILS_ENV]
new_spec = spec.clone
new_spec["database"] = customer.database_name
ActiveRecord::Base.establish_connection(new_spec)
ActiveRecord::Migrator.migrate("db/migrate_data/", nil)

Я считаю полезным впоследствии восстановить старое соединение на определенной модели:

CustomerModel.establish_connection(spec)
person Jim Puls    schedule 07.10.2008

вы можете изменить подключение к ActiveRecord в любое время, вызвав ActiveRecord::Base.install_connection(...)

IE:

 ActiveRecord::Base.establish_connection({:adapter => "mysql", :database => new_name, :host => "olddev",
    :username => "root", :password => "password" })
person Tilendor    schedule 07.10.2008
comment
Обратите внимание, что это очистит ваш кеш, поэтому он будет выполнять «Показать таблицы, такие как %eachtable%» и показать «Создать таблицу» для каждой таблицы. Проблема только в том случае, если вы устанавливаете новое соединение для каждого запроса... - person Kevin; 19.06.2013

Прошло некоторое время с тех пор, как этот вопрос был создан, но я должен сказать, что есть и другой способ:

conn_config = ActiveRecord::Base.connection_config
conn_config[:database] = new_database
ActiveRecord::Base.establish_connection conn_config
person Andre Figueiredo    schedule 27.05.2015
comment
это спасло мне жизнь! отличный упрощенный ответ! - person Darlan D.; 26.02.2019
comment
как изменить connstring, не затрагивая другой пул? - person Darlan D.; 26.02.2019
comment
Я могу ошибаться, но я почти уверен, что ActiveRecord::Base.establish_connection создает новый пул. Если у вас есть конкретная проблема, вы получите больше преимуществ, открыв новый вопрос. - person Andre Figueiredo; 27.02.2019

class Database
  def self.development!
    ActiveRecord::Base.establish_connection(:development)
  end

  def self.production!
    ActiveRecord::Base.establish_connection(ENV['PRODUCTION_DATABASE'])
  end

  def self.staging!
    ActiveRecord::Base.establish_connection(ENV['STAGING_DATABASE'])
  end
end

И в .env (например, с драгоценным камнем dotenv-rails):

PRODUCTION_DATABASE=postgres://...
STAGING_DATABASE=postgres://...

Теперь вы можете:

Database.development!
User.count
Database.production!
User.count
Database.staging!
User.count
# etc.
person Dorian    schedule 24.05.2017