class DatabaseSlave::ConnectionHandler
Public Class Methods
establish_connection()
click to toggle source
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方法的方式来达到目的.
# 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