module MultipleDbs::MultiConnectable::ClassMethods
Public Class Methods
return the database name of the database that this subclass is related to
# File lib/multiple_dbs/multi_connectable.rb, line 102 def self.connectable_type const_get("CONNECTABLE_TYPE") end
Override the connection method. Search the connection_pool that is handle the database connection, assign it to the Thread.current[const_get(“CONNECTABLE_TYPE”).to_s.underscore + “_connection”] vairable
# File lib/multiple_dbs/multi_connectable.rb, line 111 def self.connection self.connection_handler.connection_pools.each do |pool| if pool.spec.config[:database] == eval('DBConnection' + const_get("CONNECTABLE_TYPE").to_s).connection["database"] return Thread.current[const_get("CONNECTABLE_TYPE").to_s.underscore + "_connection"] = pool.connection end end end
This method call the block given by the user. If that block contains the definition of the relations parametrized like this:
class User < ApplicationRecord
make_connectable_class do |db| has_many :post, class_name: "Post#{db}" end
end
it will set the :post relation to the database handle by this subclass
# File lib/multiple_dbs/multi_connectable.rb, line 96 def self.muliple_relations @connectable_relations.call( const_get("CONNECTABLE_TYPE") ) if @connectable_relations end
Public Instance Methods
return the database name of the database that this subclass is related to
# File lib/multiple_dbs/multi_connectable.rb, line 123 def connectable_type const_get("CONNECTABLE_TYPE") end
This method define one subclass for each database you define. Why? becouse each subclass handle the connection with the specifyed database and becouse of that we does not have to turn off and on the connections between databases. It’s simple, if you have a User model and 3 databases defined db1, db2, db3 this method set the constants UserDb1, UserDb2 and UserDb3. UserDb1 handle the connection with the database db1 and so on.
EXAMPLE: class User < ApplicationRecord
make_connectable_class do |db| has_many :post, class_name: "Post#{db}" end
end
# File lib/multiple_dbs/multi_connectable.rb, line 55 def make_connectable_class(options = {},&block) only = options[:only] only = only.delete_if{ |o| !MultipleDbs::DBS.include?(o) } if only and only.any? database_list = (MultipleDbs::DBS & only) if only and only.any? database_list ||= MultipleDbs::DBS database_list.each do |db| class_eval do Object.const_set("#{self.name}#{db.capitalize}", Class.new(self) do class_eval do # This constant store the name of the database that this subclass # is handling const_set("CONNECTABLE_TYPE",db.capitalize) # This variable will store the connection_pool that is going to # handle the connections for the database. Just initializing the constant Thread.current[const_get("CONNECTABLE_TYPE").to_s.underscore + "_connection"] = nil # This filter calls the method multiple_relations # setting the relations to the database they should be set before_validation :muliple_relations # This filter calls the method multiple_relations # setting the relations to the database they should be set after_find :muliple_relations # This variable store the block given by the user... # It is thought to have the definition of the model relations # and is used my the method multiple_relations to set them adequately @connectable_relations = block_given? ? block : nil # This method call the block given by the user. If that block contains # the definition of the relations parametrized like this: # # class User < ApplicationRecord # make_connectable_class do |db| # has_many :post, class_name: "Post#{db}" # end # end # # it will set the :post relation to the database handle by this # subclass def self.muliple_relations @connectable_relations.call( const_get("CONNECTABLE_TYPE") ) if @connectable_relations end # return the database name of the database that this subclass # is related to def self.connectable_type const_get("CONNECTABLE_TYPE") end # Override the connection method. Search the connection_pool that # is handle the database connection, assign it to the # Thread.current[const_get("CONNECTABLE_TYPE").to_s.underscore + "_connection"] # vairable def self.connection self.connection_handler.connection_pools.each do |pool| if pool.spec.config[:database] == eval('DBConnection' + const_get("CONNECTABLE_TYPE").to_s).connection["database"] return Thread.current[const_get("CONNECTABLE_TYPE").to_s.underscore + "_connection"] = pool.connection end end end private # return the database name of the database that this subclass # is related to def connectable_type const_get("CONNECTABLE_TYPE") end # Call the class method multiple_relations. # This method call the block given by the user. If that block contains # the definition of the relations parametrized like this: # # class User < ApplicationRecord # make_connectable_class do |db| # has_many :post, class_name: "Post#{db}" # end # end # # it will set the :post relation to the database handle by this # subclass def muliple_relations self.class.muliple_relations end end end) # Set the relations for the current database Object.const_get("#{self.name}#{db.capitalize}").muliple_relations end end if database_list.any? end
Call the class method multiple_relations. This method call the block given by the user. If that block contains the definition of the relations parametrized like this:
class User < ApplicationRecord
make_connectable_class do |db| has_many :post, class_name: "Post#{db}" end
end
it will set the :post relation to the database handle by this subclass
# File lib/multiple_dbs/multi_connectable.rb, line 139 def muliple_relations self.class.muliple_relations end
This method lookup for the subclass related to the database that you pass as an argument and the model in wich you are calling the method. It use Object.const_get to lookup for the constant and also call the method multiple_relations so the relations match the classes that must be matched.
# File lib/multiple_dbs/multi_connectable.rb, line 34 def multiple_class(connectable_type) klass = Object.const_get("#{self.name}#{connectable_type.capitalize}") klass.muliple_relations klass end