rails-on-services / apartment

Database multi-tenancy for Rack (and Rails) applications
375 stars 146 forks source link

Switching tenants on different database connections #216

Open NielsKSchjoedt opened 1 year ago

NielsKSchjoedt commented 1 year ago

I have a rails 6.1 app with apartment 2.11.0 the following models:

# models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  connects_to database: { default: :primary, readonly: :replica }
end

# models/car.rb
class Car < ApplicationRecord
   # ...
end

# models/archive_application_record.rb
class ArchiveApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  connects_to database: { default: :archive, readonly: :archive }
end

# models/car.rb
class SoldCar < ArchiveApplicationRecord
   # ...
end

So as you can see there are two different models with two different db connections. I have an apartment config like this:

# initializers/apartment.rb
Apartment.configure do |config|
  config.use_schemas = true
  config.use_sql = true
  config.persistent_schemas = ["extensions"]
  config.prepend_environment = false
  config.append_environment = false
  config.default_tenant = "it"
  config.tenant_names = ["de", "it", "at"]
  config.tenant_presence_check = false
end

and a database.yml like so:

common: &common
  adapter: postgresql
  encoding: utf8
  host: localhost
  port: 5440
  username: postgres
  password: postgres
  template: template0 # Required for UTF8 encoding
  pool: 10
  schema_search_path: "it,extensions" # default_schema, persistent_schema

development:
  primary:
    <<: *common
    database: development
  replica:
    <<: *common
    database: development
    port: 5441
    readonly: true
  car_stats_primary:
    <<: *common
    database: archive
    port: 5442

When i do Apartment::Tenant.switch!("de") and do Car.connection.execute("SHOW search_path;").first then it gives me as expected:

#=> {"search_path"=>"de, extensions"}

or when I run ActiveRecord::Base.connected_to(role: :readonly) { Car.connection.execute("SHOW search_path;").first } it gives me:

#=> {"search_path"=>"de, extensions"}

but when I do the same for Car.connection.execute("SHOW search_path;").first then it gives me the default search path (it doesn't change)

#=> {"search_path"=>"it, extensions"}

Is this expected, and if so, how can I make apartment switch tenant on that db connection also?

gerome0123 commented 1 year ago

any update on this?

Bassem-Gh commented 5 months ago

any updates ?