Module: MultipleDbs::MultiConnectable::ClassMethods

Defined in:
lib/multiple_dbs/multi_connectable.rb

Instance Method Summary collapse

Instance Method Details

#make_connectable_class(options = {}, &block) ⇒ Object

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



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# 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

#multiple_class(connectable_type) ⇒ Object Also known as: mdb

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.



34
35
36
37
38
# 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