class Apartment::Adapters::AbstractAdapter

def connect_to_new(tenant)

Parameters:
  • 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)

Parameters:
  • 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)

Parameters:
  • 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

Returns:
  • (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

Returns:
  • (String) - current tenant name
def current_tenant
  Apartment.connection.current_database
end

def drop(tenant)

Parameters:
  • 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)

Returns:
  • (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)

Parameters:
  • 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)

Parameters:
  • 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)

Parameters:
  • 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