Если вы в состоянии контролировать и настраивать каждый Rails экземпляр, и вы можете позволить себе тратить ресурсы из-за них быть в режиме ожидания, сэкономить некоторые проблемы и просто изменить database.yml, чтобы изменить соединение с базой данных, используемое для каждого экземпляра. Если вас беспокоит производительность, этот подход не сократит его.
Для моделей, связанных с одной уникальной таблицы только с одной базой данных вы можете вызвать establish_connection внутри модели:
establish_connection "database_name_#{RAILS_ENV}"
Как описано здесь: http://apidock.com/rails/ActiveRecord/Base/establish_connection/class
Вы будете иметь некоторые модели с помощью таблиц из одной базы данных и другие модели, использующие таблицы из других баз данных.
Если у вас одинаковые таблицы, общие для разных баз данных и разделяемые одной моделью, ActiveRecord вам не поможет. Еще в 2009 году мне это потребовалось в проекте, над которым я работал, используя Rails 2.3.8. У меня была база данных для каждого клиента, и я назвал базы данных с их идентификаторами.Поэтому я создал метод, чтобы изменить соединение внутри ApplicationController:
def change_database database_id = params[:company_id]
return if database_id.blank?
configuration = ActiveRecord::Base.connection.instance_eval { @config }.clone
configuration[:database] = "database_name_#{database_id}_#{RAILS_ENV}"
MultipleDatabaseModel.establish_connection configuration
end
И добавил, что метод как before_filter на все контроллеры:
before_filter :change_database
Таким образом, для каждого действия каждого контроллера, когда PARAMS [ : company_id] определено и установлено, оно изменит базу данных на правильную.
Для обработки миграции Я продлил ActiveRecord :: Migration, с помощью метода, который выглядит для всех клиентов и перебираю блок с каждым ID:
class ActiveRecord::Migration
def self.using_databases *args
configuration = ActiveRecord::Base.connection.instance_eval { @config }
former_database = configuration[:database]
companies = args.blank? ? Company.all : Company.find(args)
companies.each do |company|
configuration[:database] = "database_name_#{company[:id]}_#{RAILS_ENV}"
ActiveRecord::Base.establish_connection configuration
yield self
end
configuration[:database] = former_database
ActiveRecord::Base.establish_connection configuration
end
end
Обратите внимание, что, делая это, было бы невозможно для вас делать запросы в рамках одного действия из двух разных баз данных. Вы можете снова позвонить change_database, но он будет неприятным при попытке использовать методы, выполняющие запросы, из объектов, которые больше не связаны с правильной базой данных. Кроме того, очевидно, что вы не сможете присоединиться к таблицам, принадлежащим различным базам данных.
Чтобы справиться с этим, ActiveRecord должен быть значительно расширен. К настоящему моменту должен быть плагин, который поможет вам в решении этой проблемы. Быстрое исследование дало мне этот:
DB-Заклинатель: http://kovyrin.github.com/db-charmer/
Я готов попробовать. Дайте мне знать, что сработает для вас.
http://imnithin.github.io/multiple-database.html – Nithin