Class: DatabaseSlave::ConnectionHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/database_slave/connection_handler.rb

Class Method Summary collapse

Class Method Details

.establish_connectionObject

Description

该方法根据 DatabaseSlave::Configuration 的配置建立所有的数据库从库链接.

Rails在启动时会调用 ActiveRecord::Base.establish_connection 来建立database.yml连接, 以上方法定义在 active_record/connection_adapters/abstract/connection_specification.rb

故该方法的设计参考了以上方法, 遵循了以上方法的设计逻辑.

注意下面方法中 klass 的实现:

因为remove_connection方法需要一个类名作为参数, 然后会在该类名上调用name方法.
查看源码可知原方法传入的是self, 即当前调用类; 类自带了name方法.

同理, 这里我们也应该传入一个类名, 但self不是所期望的, 于是这里使用了

  self.const_set(slave_name.to_s.strip.camelize, Class.new)

的方式动态地创建了一个类.

此外, 还可以通过定义一个代理类Proxy然后实现name方法的方式来达到目的.


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/database_slave/connection_handler.rb', line 24

def self.establish_connection
  ActiveRecord::Base.slave_connections ||= []

  DatabaseSlave.configurations.each do |slave_name, config|
    adapter_method = "#{config['adapter']}_connection"
    spec           = ActiveRecord::Base::ConnectionSpecification.new(config, adapter_method)
    klass          = self.const_set(slave_name.to_s.strip.camelize, Class.new)

    unless ActiveRecord::Base.respond_to?(spec.adapter_method)
      raise DatabaseSlave::AdapterNotFound,
        "database configuration specifies not include #{config['adapter']} adapter"
    end

    ActiveRecord::Base.slave_connections << klass.name
    ActiveRecord::Base.remove_connection klass
    ActiveRecord::Base.connection_handler.establish_connection klass.name, spec
  end
end