Nếu bạn có thể kiểm soát và cấu hình mỗi Rails dụ, và bạn có thể đủ khả năng lãng phí tài nguyên vì trong số đó là ở chế độ chờ, tiết kiệm cho mình một số rắc rối và chỉ cần thay đổi database.yml để sửa đổi kết nối cơ sở dữ liệu được sử dụng trên mọi cá thể. Nếu bạn lo ngại về hiệu suất, cách tiếp cận này sẽ không cắt nó.
Đối với mô hình ràng buộc vào một bảng độc đáo duy nhất trên chỉ có một cơ sở dữ liệu bạn có thể gọi establish_connection bên trong mô hình:
establish_connection "database_name_#{RAILS_ENV}"
Như đã trình bày ở đây: http://apidock.com/rails/ActiveRecord/Base/establish_connection/class
Bạn sẽ có một số mô hình sử dụng bảng từ một cơ sở dữ liệu và các mô hình khác sử dụng bảng từ cơ sở dữ liệu khác.
Nếu bạn có bảng giống hệt nhau, phổ biến trên các cơ sở dữ liệu khác nhau và được chia sẻ bởi một mô hình duy nhất, ActiveRecord sẽ không giúp bạn. Trở lại năm 2009 tôi yêu cầu điều này trên một dự án tôi đã làm việc trên, bằng cách sử dụng Rails 2.3.8. Tôi đã có một cơ sở dữ liệu cho mỗi khách hàng, và tôi đặt tên cho các cơ sở dữ liệu với các ID của họ.Vì vậy, tôi đã tạo ra một phương pháp để thay đổi các kết nối bên trong 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
Và thêm phương pháp đó như là một before_filter cho tất cả các bộ điều khiển:
before_filter :change_database
Vì vậy, đối với mỗi hành động của mỗi bộ điều khiển, khi params [ : company_id] được xác định và đặt, nó sẽ thay đổi cơ sở dữ liệu thành đúng.
Để xử lý di cư Tôi mở rộng ActiveRecord :: Migration, với một phương pháp mà sẽ tìm kiếm tất cả các khách hàng và lặp một khối với mỗi 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
Lưu ý rằng bằng cách làm này, nó sẽ không thể cho bạn để thực hiện các truy vấn trong cùng một hành động từ hai cơ sở dữ liệu khác nhau. Bạn có thể gọi change_database một lần nữa nhưng sẽ khó chịu khi bạn thử sử dụng các phương thức thực hiện truy vấn, từ các đối tượng không còn được liên kết với cơ sở dữ liệu chính xác nữa. Ngoài ra, rõ ràng là bạn sẽ không thể tham gia các bảng thuộc về các cơ sở dữ liệu khác nhau.
Để xử lý đúng cách này, ActiveRecord sẽ được mở rộng đáng kể. Nên có một plugin ngay bây giờ để giúp bạn với vấn đề này. Một nghiên cứu nhanh chóng đã cho tôi một điều này:
DB-Charmer: http://kovyrin.github.com/db-charmer/
tôi sẵn sàng thử nó. Hãy cho tôi biết những gì làm việc cho bạn.
http://imnithin.github.io/multiple-database.html – Nithin