Skip to content

Commit

Permalink
[Resolves #42] After switch callback not working with nil argument
Browse files Browse the repository at this point in the history
- Each adapter is responsible for resetting the tenant info based on the way they behave
- `switch` relies on the `connect_to_new` implementation of each of the adapters
- Added test coverage for raised issue
  • Loading branch information
rpbaltazar authored May 5, 2020
2 parents b99748a + 61ee211 commit bed491a
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 10 deletions.
18 changes: 8 additions & 10 deletions lib/apartment/adapters/abstract_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ def drop(tenant)
#
def switch!(tenant = nil)
run_callbacks :switch do
return reset if tenant.nil?

connect_to_new(tenant).tap do
Apartment.connection.clear_query_cache
end
Expand Down Expand Up @@ -130,14 +128,12 @@ def seed_data
# @return {String} tenant name with Rails environment *optionally* prepended
#
def environmentify(tenant)
if !tenant.include?(Rails.env)
if Apartment.prepend_environment
"#{Rails.env}_#{tenant}"
elsif Apartment.append_environment
"#{tenant}_#{Rails.env}"
else
tenant
end
return tenant if tenant.nil? || tenant.include?(Rails.env)

if Apartment.prepend_environment
"#{Rails.env}_#{tenant}"
elsif Apartment.append_environment
"#{tenant}_#{Rails.env}"
else
tenant
end
Expand Down Expand Up @@ -175,6 +171,8 @@ def create_tenant_command(conn, tenant)
# @param {String} tenant Database name
#
def connect_to_new(tenant)
return reset if tenant.nil?

query_cache_enabled = ActiveRecord::Base.connection.query_cache_enabled

Apartment.establish_connection multi_tenantify(tenant)
Expand Down
2 changes: 2 additions & 0 deletions lib/apartment/adapters/sqlite3_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ def current
protected

def connect_to_new(tenant)
return reset if tenant.nil?

unless File.exist?(database_file(tenant))
raise TenantNotFound,
"The tenant #{environmentify(tenant)} cannot be found."
Expand Down
1 change: 1 addition & 0 deletions spec/adapters/jdbc_mysql_adapter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def tenant_names

let(:default_tenant) { subject.switch { ActiveRecord::Base.connection.current_database } }

it_should_behave_like 'a generic apartment adapter callbacks'
it_should_behave_like 'a generic apartment adapter'
it_should_behave_like 'a connection based apartment adapter'
end
Expand Down
2 changes: 2 additions & 0 deletions spec/adapters/jdbc_postgresql_adapter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
describe Apartment::Adapters::JDBCPostgresqlAdapter, database: :postgresql do
subject { Apartment::Tenant.jdbc_postgresql_adapter config.symbolize_keys }

it_should_behave_like 'a generic apartment adapter callbacks'

context 'using schemas' do
before { Apartment.use_schemas = true }

Expand Down
2 changes: 2 additions & 0 deletions spec/adapters/mysql2_adapter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ def tenant_names

let(:default_tenant) { subject.switch { ActiveRecord::Base.connection.current_database } }

it_should_behave_like 'a generic apartment adapter callbacks'

context 'using - the equivalent of - schemas' do
before { Apartment.use_schemas = true }

Expand Down
2 changes: 2 additions & 0 deletions spec/adapters/postgresql_adapter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

subject { Apartment::Tenant.postgresql_adapter config }

it_should_behave_like 'a generic apartment adapter callbacks'

context 'using schemas with schema.rb' do
before { Apartment.use_schemas = true }

Expand Down
2 changes: 2 additions & 0 deletions spec/adapters/sqlite3_adapter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

subject { Apartment::Tenant.sqlite3_adapter config }

it_should_behave_like 'a generic apartment adapter callbacks'

context 'using connections' do
def tenant_names
db_dir = File.expand_path('../dummy/db', __dir__)
Expand Down
57 changes: 57 additions & 0 deletions spec/examples/generic_adapters_callbacks_examples.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# frozen_string_literal: true

require 'spec_helper'

shared_examples_for 'a generic apartment adapter callbacks' do
class MyProc
def self.call(tenant_name); end
end

include Apartment::Spec::AdapterRequirements

before do
Apartment.prepend_environment = false
Apartment.append_environment = false
end

describe '#switch!' do
before do
Apartment::Adapters::AbstractAdapter.set_callback :switch, :before do
MyProc.call(Apartment::Tenant.current)
end

Apartment::Adapters::AbstractAdapter.set_callback :switch, :after do
MyProc.call(Apartment::Tenant.current)
end

allow(MyProc).to receive(:call)
end

# NOTE: Part of the test setup creates and switches tenants, so we need
# to reset the callbacks to ensure that each test run has the correct
# counts
after do
Apartment::Adapters::AbstractAdapter.reset_callbacks :switch
end

context 'when tenant is nil' do
before do
Apartment::Tenant.switch!(nil)
end

it 'runs both before and after callbacks' do
expect(MyProc).to have_received(:call).twice
end
end

context 'when tenant is not nil' do
before do
Apartment::Tenant.switch!(db1)
end

it 'runs both before and after callbacks' do
expect(MyProc).to have_received(:call).twice
end
end
end
end

0 comments on commit bed491a

Please sign in to comment.