class Apartment::Adapters::AbstractAdapter
def connect_to_new(tenant)
-
tenant
(String
) -- Database name
def connect_to_new(tenant) Apartment.establish_connection multi_tenantify(tenant) Apartment.connection.active? # call active? to manually check if this connection is valid rescue *rescuable_exceptions raise DatabaseNotFound, "The tenant #{environmentify(tenant)} cannot be found." end
def create(tenant)
-
tenant
(String
) -- Tenant name
def create(tenant) create_tenant(tenant) process(tenant) do import_database_schema # Seed data if appropriate seed_data if Apartment.seed_after_create yield if block_given? end end
def create_tenant(tenant)
-
tenant
(String
) -- Database name
def create_tenant(tenant) Apartment.connection.create_database( environmentify(tenant) ) rescue *rescuable_exceptions raise DatabaseExists, "The tenant #{environmentify(tenant)} already exists." end
def current
Note alias_method here doesn't work with inheritence apparently ??
def current current_tenant end
def current_database
-
(String)
- current tenant name
def current_database warn "[Deprecation Warning] `current_database` is now deprecated, please use `current_tenant`" current_tenant end
def current_tenant
-
(String)
- current tenant name
def current_tenant Apartment.connection.current_database end
def drop(tenant)
-
tenant
(String
) -- Database name
def drop(tenant) # Apartment.connection.drop_database note that drop_database will not throw an exception, so manually execute Apartment.connection.execute("DROP DATABASE #{environmentify(tenant)}" ) rescue *rescuable_exceptions raise DatabaseNotFound, "The tenant #{environmentify(tenant)} cannot be found" end
def environmentify(tenant)
-
(String)
- tenant name with Rails environment *optionally* prepended
Parameters:
-
tenant
(String
) -- Database name
def environmentify(tenant) unless tenant.include?(Rails.env) if Apartment.prepend_environment "#{Rails.env}_#{tenant}" elsif Apartment.append_environment "#{tenant}_#{Rails.env}" else tenant end else tenant end end
def import_database_schema
Import the database schema
def import_database_schema ActiveRecord::Schema.verbose = false # do not log schema load output. load_or_abort(Apartment.database_schema_file) if Apartment.database_schema_file end
def initialize(config)
-
config
(Hash
) -- Database config
def initialize(config) @config = config end
def load_or_abort(file)
Load a file or abort if it doesn't exists
def load_or_abort(file) if File.exists?(file) load(file) else abort %{#{file} doesn't exist yet} end end
def multi_tenantify(tenant)
Return a new config that is multi-tenanted
def multi_tenantify(tenant) @config.clone.tap do |config| config[:database] = environmentify(tenant) end end
def process(tenant = nil)
-
tenant
(String?
) -- Database or schema to connect to
def process(tenant = nil) previous_tenant = current_tenant switch(tenant) yield if block_given? ensure switch(previous_tenant) rescue reset end
def process_excluded_models
Establish a new connection for each specific excluded model
def process_excluded_models # All other models will shared a connection (at Apartment.connection_class) and we can modify at will Apartment.excluded_models.each do |excluded_model| excluded_model.constantize.establish_connection @config end end
def rescuable_exceptions
Exceptions to rescue from on db operations
def rescuable_exceptions [ActiveRecord::ActiveRecordError] + [rescue_from].flatten end
def rescue_from
Extra exceptions to rescue from
def rescue_from [] end
def reset
Reset the tenant connection to the default
def reset Apartment.establish_connection @config end
def seed_data
Load the rails seed file into the db
def seed_data silence_stream(STDOUT){ load_or_abort("#{Rails.root}/db/seeds.rb") } # Don't log the output of seeding the db end
def switch(tenant = nil)
-
tenant
(String
) -- Database name
def switch(tenant = nil) # Just connect to default db and return return reset if tenant.nil? connect_to_new(tenant).tap do ActiveRecord::Base.connection.clear_query_cache end end