将activerecord与嵌套数据库一起使用

时间:2013-07-14 07:23:05

标签: ruby-on-rails database activerecord model

我正在构建一个rails应用程序来存储许多不同的,用户提供的数据库连接,并针对每个数据库连接执行任意sql。我将每个数据库连接字符串表示为“连接”模型的实例,并希望能够编写一个方法来查询每个连接所代表的数据库,理想情况下使用activerecord ORM。但是,当我在以下代码中使用establish_connection方法时,我写的代码会覆盖整个连接表的数据库连接。您如何建议我更改代码以查询任意数据库,而不覆盖整个Connections表的连接?

class Connection < ActiveRecord::Base
  validates_presence_of :host, :port, :db_name, :db_user, :db_password, :db_type

  def connect
    self.connection = ActiveRecord::Base.establish_connection(
      adapter: self.db_type,
      host: self.host,
      database: self.db_name,
      username: self.db_user,
      password: self.db_password
    )
  end

end

1 个答案:

答案 0 :(得分:1)

这样做的好方法是为您需要的每个数据库连接建立一个模型,然后将其他模型作为它们的子类。所以,例如:

  1. 在database.yml(每个环境)中定义所有需要的连接
  2.     # DB 1
        development:
          adapter: mysql2
          encoding: utf8
          database: db_1
          username: ****
          password: ****
          host: ********
          pool: 5
          ...
    
        # DB 2
        db2_development:
          adapter: mysql2
          encoding: utf8
          database: db_2
          username: ****
          password: ****
          host: ********
          pool: 5
          ...
    
        # Same for production (and/or other environments)
        production:
          ...
        db2_production:
          ...
    
    1. 为每个数据库定义一个“主”模型,该模型继承自ActiveRecord::Base
    2.     # DB1
          class DB1 < ActiveRecord::Base
            self.abstract_class = true
          end
      
          # DB2
          class DB2 < ActiveRecord::Base
            self.abstract_class = true
            establish_connection "db2_#{Rails.env}"
          end
      
          ...
      
      1. 现在将所有特定于数据库的模型定义为上面定义的模型的子类,以这种方式:
      2.     # DB1 specific model
            class DB1_model < DB1
              # model logic here
            end
        
            # DB2 specific model
            class DB2_model < DB2
               # model logic here
            end
        
            ...
        

        你很高兴。

        通过这种方式,您可以连接到不同环境中的N个数据库(通常为developmentstagingpreprodproduction,但在您的情况下可能会有所不同)。

        另外,请记住Rails将为每个数据库管理一个SQL连接池。

        在上面的示例中,Rails将为每个数据库打开最多 5个连接,因此总计将 10 (对于单个应用程序实例)。 如果您使用Phusion Passenger或Unicorn,并生成8个应用程序实例,则总SQL连接将(最多)10 * 8 = 80。