ros-apartment 2.3.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE.md +21 -0
  3. data/.gitignore +15 -0
  4. data/.pryrc +3 -0
  5. data/.rspec +4 -0
  6. data/.travis.yml +65 -0
  7. data/Appraisals +71 -0
  8. data/Gemfile +10 -0
  9. data/Guardfile +24 -0
  10. data/HISTORY.md +398 -0
  11. data/README.md +576 -0
  12. data/Rakefile +128 -0
  13. data/TODO.md +51 -0
  14. data/apartment.gemspec +46 -0
  15. data/docker-compose.yml +33 -0
  16. data/gemfiles/rails_4_2.gemfile +23 -0
  17. data/gemfiles/rails_5_0.gemfile +22 -0
  18. data/gemfiles/rails_5_1.gemfile +22 -0
  19. data/gemfiles/rails_5_2.gemfile +18 -0
  20. data/gemfiles/rails_6_0.gemfile +22 -0
  21. data/gemfiles/rails_master.gemfile +22 -0
  22. data/lib/apartment.rb +118 -0
  23. data/lib/apartment/adapters/abstract_adapter.rb +269 -0
  24. data/lib/apartment/adapters/abstract_jdbc_adapter.rb +18 -0
  25. data/lib/apartment/adapters/jdbc_mysql_adapter.rb +19 -0
  26. data/lib/apartment/adapters/jdbc_postgresql_adapter.rb +56 -0
  27. data/lib/apartment/adapters/mysql2_adapter.rb +71 -0
  28. data/lib/apartment/adapters/postgis_adapter.rb +12 -0
  29. data/lib/apartment/adapters/postgresql_adapter.rb +236 -0
  30. data/lib/apartment/adapters/sqlite3_adapter.rb +56 -0
  31. data/lib/apartment/console.rb +12 -0
  32. data/lib/apartment/deprecation.rb +10 -0
  33. data/lib/apartment/elevators/domain.rb +22 -0
  34. data/lib/apartment/elevators/first_subdomain.rb +17 -0
  35. data/lib/apartment/elevators/generic.rb +32 -0
  36. data/lib/apartment/elevators/host.rb +30 -0
  37. data/lib/apartment/elevators/host_hash.rb +22 -0
  38. data/lib/apartment/elevators/subdomain.rb +62 -0
  39. data/lib/apartment/migrator.rb +51 -0
  40. data/lib/apartment/railtie.rb +67 -0
  41. data/lib/apartment/reloader.rb +21 -0
  42. data/lib/apartment/tasks/enhancements.rb +57 -0
  43. data/lib/apartment/tenant.rb +66 -0
  44. data/lib/apartment/version.rb +3 -0
  45. data/lib/generators/apartment/install/USAGE +5 -0
  46. data/lib/generators/apartment/install/install_generator.rb +10 -0
  47. data/lib/generators/apartment/install/templates/apartment.rb +109 -0
  48. data/lib/tasks/apartment.rake +145 -0
  49. data/spec/adapters/jdbc_mysql_adapter_spec.rb +19 -0
  50. data/spec/adapters/jdbc_postgresql_adapter_spec.rb +41 -0
  51. data/spec/adapters/mysql2_adapter_spec.rb +59 -0
  52. data/spec/adapters/postgresql_adapter_spec.rb +61 -0
  53. data/spec/adapters/sqlite3_adapter_spec.rb +83 -0
  54. data/spec/apartment_spec.rb +11 -0
  55. data/spec/config/database.yml.sample +49 -0
  56. data/spec/dummy/Rakefile +7 -0
  57. data/spec/dummy/app/controllers/application_controller.rb +6 -0
  58. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  59. data/spec/dummy/app/models/company.rb +3 -0
  60. data/spec/dummy/app/models/user.rb +3 -0
  61. data/spec/dummy/app/views/application/index.html.erb +1 -0
  62. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  63. data/spec/dummy/config.ru +4 -0
  64. data/spec/dummy/config/application.rb +49 -0
  65. data/spec/dummy/config/boot.rb +11 -0
  66. data/spec/dummy/config/database.yml.sample +44 -0
  67. data/spec/dummy/config/environment.rb +5 -0
  68. data/spec/dummy/config/environments/development.rb +28 -0
  69. data/spec/dummy/config/environments/production.rb +51 -0
  70. data/spec/dummy/config/environments/test.rb +34 -0
  71. data/spec/dummy/config/initializers/apartment.rb +4 -0
  72. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  73. data/spec/dummy/config/initializers/inflections.rb +10 -0
  74. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  75. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  76. data/spec/dummy/config/initializers/session_store.rb +8 -0
  77. data/spec/dummy/config/locales/en.yml +5 -0
  78. data/spec/dummy/config/routes.rb +3 -0
  79. data/spec/dummy/db/migrate/20110613152810_create_dummy_models.rb +39 -0
  80. data/spec/dummy/db/migrate/20111202022214_create_table_books.rb +14 -0
  81. data/spec/dummy/db/migrate/20180415260934_create_public_tokens.rb +13 -0
  82. data/spec/dummy/db/schema.rb +55 -0
  83. data/spec/dummy/db/seeds.rb +5 -0
  84. data/spec/dummy/db/seeds/import.rb +5 -0
  85. data/spec/dummy/public/404.html +26 -0
  86. data/spec/dummy/public/422.html +26 -0
  87. data/spec/dummy/public/500.html +26 -0
  88. data/spec/dummy/public/favicon.ico +0 -0
  89. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  90. data/spec/dummy/script/rails +6 -0
  91. data/spec/dummy_engine/.gitignore +8 -0
  92. data/spec/dummy_engine/Gemfile +15 -0
  93. data/spec/dummy_engine/Rakefile +34 -0
  94. data/spec/dummy_engine/bin/rails +12 -0
  95. data/spec/dummy_engine/config/initializers/apartment.rb +51 -0
  96. data/spec/dummy_engine/dummy_engine.gemspec +24 -0
  97. data/spec/dummy_engine/lib/dummy_engine.rb +4 -0
  98. data/spec/dummy_engine/lib/dummy_engine/engine.rb +4 -0
  99. data/spec/dummy_engine/lib/dummy_engine/version.rb +3 -0
  100. data/spec/dummy_engine/test/dummy/Rakefile +6 -0
  101. data/spec/dummy_engine/test/dummy/config.ru +4 -0
  102. data/spec/dummy_engine/test/dummy/config/application.rb +22 -0
  103. data/spec/dummy_engine/test/dummy/config/boot.rb +5 -0
  104. data/spec/dummy_engine/test/dummy/config/database.yml +25 -0
  105. data/spec/dummy_engine/test/dummy/config/environment.rb +5 -0
  106. data/spec/dummy_engine/test/dummy/config/environments/development.rb +37 -0
  107. data/spec/dummy_engine/test/dummy/config/environments/production.rb +78 -0
  108. data/spec/dummy_engine/test/dummy/config/environments/test.rb +39 -0
  109. data/spec/dummy_engine/test/dummy/config/initializers/assets.rb +8 -0
  110. data/spec/dummy_engine/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  111. data/spec/dummy_engine/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  112. data/spec/dummy_engine/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  113. data/spec/dummy_engine/test/dummy/config/initializers/inflections.rb +16 -0
  114. data/spec/dummy_engine/test/dummy/config/initializers/mime_types.rb +4 -0
  115. data/spec/dummy_engine/test/dummy/config/initializers/session_store.rb +3 -0
  116. data/spec/dummy_engine/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  117. data/spec/dummy_engine/test/dummy/config/locales/en.yml +23 -0
  118. data/spec/dummy_engine/test/dummy/config/routes.rb +56 -0
  119. data/spec/dummy_engine/test/dummy/config/secrets.yml +22 -0
  120. data/spec/examples/connection_adapter_examples.rb +42 -0
  121. data/spec/examples/generic_adapter_custom_configuration_example.rb +95 -0
  122. data/spec/examples/generic_adapter_examples.rb +163 -0
  123. data/spec/examples/schema_adapter_examples.rb +234 -0
  124. data/spec/integration/apartment_rake_integration_spec.rb +107 -0
  125. data/spec/integration/query_caching_spec.rb +81 -0
  126. data/spec/integration/use_within_an_engine_spec.rb +28 -0
  127. data/spec/schemas/v1.rb +16 -0
  128. data/spec/schemas/v2.rb +43 -0
  129. data/spec/schemas/v3.rb +49 -0
  130. data/spec/spec_helper.rb +61 -0
  131. data/spec/support/apartment_helpers.rb +43 -0
  132. data/spec/support/capybara_sessions.rb +15 -0
  133. data/spec/support/config.rb +10 -0
  134. data/spec/support/contexts.rb +52 -0
  135. data/spec/support/requirements.rb +35 -0
  136. data/spec/support/setup.rb +46 -0
  137. data/spec/tasks/apartment_rake_spec.rb +129 -0
  138. data/spec/tenant_spec.rb +190 -0
  139. data/spec/unit/config_spec.rb +112 -0
  140. data/spec/unit/elevators/domain_spec.rb +32 -0
  141. data/spec/unit/elevators/first_subdomain_spec.rb +24 -0
  142. data/spec/unit/elevators/generic_spec.rb +54 -0
  143. data/spec/unit/elevators/host_hash_spec.rb +32 -0
  144. data/spec/unit/elevators/host_spec.rb +89 -0
  145. data/spec/unit/elevators/subdomain_spec.rb +76 -0
  146. data/spec/unit/migrator_spec.rb +77 -0
  147. data/spec/unit/reloader_spec.rb +24 -0
  148. metadata +487 -0
@@ -0,0 +1,62 @@
1
+ require 'apartment/elevators/generic'
2
+ require 'public_suffix'
3
+
4
+ module Apartment
5
+ module Elevators
6
+ # Provides a rack based tenant switching solution based on subdomains
7
+ # Assumes that tenant name should match subdomain
8
+ #
9
+ class Subdomain < Generic
10
+ def self.excluded_subdomains
11
+ @excluded_subdomains ||= []
12
+ end
13
+
14
+ def self.excluded_subdomains=(arg)
15
+ @excluded_subdomains = arg
16
+ end
17
+
18
+ def parse_tenant_name(request)
19
+ request_subdomain = subdomain(request.host)
20
+
21
+ # If the domain acquired is set to be excluded, set the tenant to whatever is currently
22
+ # next in line in the schema search path.
23
+ tenant = if self.class.excluded_subdomains.include?(request_subdomain)
24
+ nil
25
+ else
26
+ request_subdomain
27
+ end
28
+
29
+ tenant.presence
30
+ end
31
+
32
+ protected
33
+
34
+ # *Almost* a direct ripoff of ActionDispatch::Request subdomain methods
35
+
36
+ # Only care about the first subdomain for the database name
37
+ def subdomain(host)
38
+ subdomains(host).first
39
+ end
40
+
41
+ def subdomains(host)
42
+ host_valid?(host) ? parse_host(host) : []
43
+ end
44
+
45
+ def host_valid?(host)
46
+ !ip_host?(host) && domain_valid?(host)
47
+ end
48
+
49
+ def ip_host?(host)
50
+ !/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/.match(host).nil?
51
+ end
52
+
53
+ def domain_valid?(host)
54
+ PublicSuffix.valid?(host, ignore_private: true)
55
+ end
56
+
57
+ def parse_host(host)
58
+ (PublicSuffix.parse(host, ignore_private: true).trd || '').split('.')
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,51 @@
1
+ require 'apartment/tenant'
2
+
3
+ module Apartment
4
+ module Migrator
5
+
6
+ extend self
7
+
8
+ # Migrate to latest
9
+ def migrate(database)
10
+ Tenant.switch(database) do
11
+ version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
12
+
13
+ migration_scope_block = -> (migration) { ENV["SCOPE"].blank? || (ENV["SCOPE"] == migration.scope) }
14
+
15
+ if activerecord_below_5_2?
16
+ ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, version, &migration_scope_block)
17
+ else
18
+ ActiveRecord::Base.connection.migration_context.migrate(version, &migration_scope_block)
19
+ end
20
+ end
21
+ end
22
+
23
+ # Migrate up/down to a specific version
24
+ def run(direction, database, version)
25
+ Tenant.switch(database) do
26
+ if activerecord_below_5_2?
27
+ ActiveRecord::Migrator.run(direction, ActiveRecord::Migrator.migrations_paths, version)
28
+ else
29
+ ActiveRecord::Base.connection.migration_context.run(direction, version)
30
+ end
31
+ end
32
+ end
33
+
34
+ # rollback latest migration `step` number of times
35
+ def rollback(database, step = 1)
36
+ Tenant.switch(database) do
37
+ if activerecord_below_5_2?
38
+ ActiveRecord::Migrator.rollback(ActiveRecord::Migrator.migrations_paths, step)
39
+ else
40
+ ActiveRecord::Base.connection.migration_context.rollback(step)
41
+ end
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def activerecord_below_5_2?
48
+ ActiveRecord.version.release < Gem::Version.new('5.2.0')
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,67 @@
1
+ require 'rails'
2
+ require 'apartment/tenant'
3
+ require 'apartment/reloader'
4
+
5
+ module Apartment
6
+ class Railtie < Rails::Railtie
7
+
8
+ #
9
+ # Set up our default config options
10
+ # Do this before the app initializers run so we don't override custom settings
11
+ #
12
+ config.before_initialize do
13
+ Apartment.configure do |config|
14
+ config.excluded_models = []
15
+ config.use_schemas = true
16
+ config.tenant_names = []
17
+ config.seed_after_create = false
18
+ config.prepend_environment = false
19
+ config.append_environment = false
20
+ end
21
+
22
+ ActiveRecord::Migrator.migrations_paths = Rails.application.paths['db/migrate'].to_a
23
+ end
24
+
25
+ # Hook into ActionDispatch::Reloader to ensure Apartment is properly initialized
26
+ # Note that this doens't entirely work as expected in Development, because this is called before classes are reloaded
27
+ # See the middleware/console declarations below to help with this. Hope to fix that soon.
28
+ #
29
+ config.to_prepare do
30
+ next if ARGV.any? { |arg| arg =~ /\Aassets:(?:precompile|clean)\z/ }
31
+
32
+ begin
33
+ Apartment.connection_class.connection_pool.with_connection do
34
+ Apartment::Tenant.init
35
+ end
36
+ rescue ::ActiveRecord::NoDatabaseError
37
+ # Since `db:create` and other tasks invoke this block from Rails 5.2.0,
38
+ # we need to swallow the error to execute `db:create` properly.
39
+ end
40
+ end
41
+
42
+ #
43
+ # Ensure rake tasks are loaded
44
+ #
45
+ rake_tasks do
46
+ load 'tasks/apartment.rake'
47
+ require 'apartment/tasks/enhancements' if Apartment.db_migrate_tenants
48
+ end
49
+
50
+ #
51
+ # The following initializers are a workaround to the fact that I can't properly hook into the rails reloader
52
+ # Note this is technically valid for any environment where cache_classes is false, for us, it's just development
53
+ #
54
+ if Rails.env.development?
55
+
56
+ # Apartment::Reloader is middleware to initialize things properly on each request to dev
57
+ initializer 'apartment.init' do |app|
58
+ app.config.middleware.use Apartment::Reloader
59
+ end
60
+
61
+ # Overrides reload! to also call Apartment::Tenant.init as well so that the reloaded classes have the proper table_names
62
+ console do
63
+ require 'apartment/console'
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,21 @@
1
+ module Apartment
2
+ class Reloader
3
+
4
+ # Middleware used in development to init Apartment for each request
5
+ # Necessary due to code reload (annoying). When models are reloaded, they no longer have the proper table_name
6
+ # That is prepended with the schema (if using postgresql schemas)
7
+ # I couldn't figure out how to properly hook into the Rails reload process *after* files are reloaded
8
+ # so I've used this in the meantime.
9
+ #
10
+ # Also see apartment/console for the re-definition of reload! that re-init's Apartment
11
+ #
12
+ def initialize(app)
13
+ @app = app
14
+ end
15
+
16
+ def call(env)
17
+ Tenant.init
18
+ @app.call(env)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,57 @@
1
+ # Require this file to append Apartment rake tasks to ActiveRecord db rake tasks
2
+ # Enabled by default in the initializer
3
+
4
+ module Apartment
5
+ class RakeTaskEnhancer
6
+
7
+ module TASKS
8
+ ENHANCE_BEFORE = %w(db:drop)
9
+ ENHANCE_AFTER = %w(db:migrate db:rollback db:migrate:up db:migrate:down db:migrate:redo db:seed)
10
+ freeze
11
+ end
12
+
13
+ # This is a bit convoluted, but helps solve problems when using Apartment within an engine
14
+ # See spec/integration/use_within_an_engine.rb
15
+
16
+ class << self
17
+ def enhance!
18
+ return unless should_enhance?
19
+
20
+ # insert task before
21
+ TASKS::ENHANCE_BEFORE.each do |name|
22
+ task = Rake::Task[name]
23
+ enhance_before_task(task)
24
+ end
25
+
26
+ # insert task after
27
+ TASKS::ENHANCE_AFTER.each do |name|
28
+ task = Rake::Task[name]
29
+ enhance_after_task(task)
30
+ end
31
+
32
+ end
33
+
34
+ def should_enhance?
35
+ Apartment.db_migrate_tenants
36
+ end
37
+
38
+ def enhance_before_task(task)
39
+ task.enhance([inserted_task_name(task)])
40
+ end
41
+
42
+ def enhance_after_task(task)
43
+ task.enhance do
44
+ Rake::Task[inserted_task_name(task)].invoke
45
+ end
46
+ end
47
+
48
+ def inserted_task_name(task)
49
+ task.name.sub(/db:/, 'apartment:')
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+ end
56
+
57
+ Apartment::RakeTaskEnhancer.enhance!
@@ -0,0 +1,66 @@
1
+ require 'forwardable'
2
+
3
+ module Apartment
4
+ # The main entry point to Apartment functions
5
+ #
6
+ module Tenant
7
+
8
+ extend self
9
+ extend Forwardable
10
+
11
+ def_delegators :adapter, :create, :drop, :switch, :switch!, :current, :each, :reset, :set_callback, :seed, :current_tenant, :default_tenant, :environmentify
12
+
13
+ attr_writer :config
14
+
15
+ # Initialize Apartment config options such as excluded_models
16
+ #
17
+ def init
18
+ adapter.process_excluded_models
19
+ end
20
+
21
+ # Fetch the proper multi-tenant adapter based on Rails config
22
+ #
23
+ # @return {subclass of Apartment::AbstractAdapter}
24
+ #
25
+ def adapter
26
+ Thread.current[:apartment_adapter] ||= begin
27
+ adapter_method = "#{config[:adapter]}_adapter"
28
+
29
+ if defined?(JRUBY_VERSION)
30
+ if config[:adapter] =~ /mysql/
31
+ adapter_method = 'jdbc_mysql_adapter'
32
+ elsif config[:adapter] =~ /postgresql/
33
+ adapter_method = 'jdbc_postgresql_adapter'
34
+ end
35
+ end
36
+
37
+ begin
38
+ require "apartment/adapters/#{adapter_method}"
39
+ rescue LoadError
40
+ raise "The adapter `#{adapter_method}` is not yet supported"
41
+ end
42
+
43
+ unless respond_to?(adapter_method)
44
+ raise AdapterNotFound, "database configuration specifies nonexistent #{config[:adapter]} adapter"
45
+ end
46
+
47
+ send(adapter_method, config)
48
+ end
49
+ end
50
+
51
+ # Reset config and adapter so they are regenerated
52
+ #
53
+ def reload!(config = nil)
54
+ Thread.current[:apartment_adapter] = nil
55
+ @config = config
56
+ end
57
+
58
+ private
59
+
60
+ # Fetch the rails database configuration
61
+ #
62
+ def config
63
+ @config ||= Apartment.connection_config
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,3 @@
1
+ module Apartment
2
+ VERSION = "2.3.0.alpha1"
3
+ end
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Creates an initializer for apartment.
3
+
4
+ Example:
5
+ `rails generate apartment:install`
@@ -0,0 +1,10 @@
1
+ module Apartment
2
+ class InstallGenerator < Rails::Generators::Base
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ def copy_files
6
+ template "apartment.rb", File.join("config", "initializers", "apartment.rb")
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,109 @@
1
+ # You can have Apartment route to the appropriate Tenant by adding some Rack middleware.
2
+ # Apartment can support many different "Elevators" that can take care of this routing to your data.
3
+ # Require whichever Elevator you're using below or none if you have a custom one.
4
+ #
5
+ # require 'apartment/elevators/generic'
6
+ # require 'apartment/elevators/domain'
7
+ require 'apartment/elevators/subdomain'
8
+ # require 'apartment/elevators/first_subdomain'
9
+ # require 'apartment/elevators/host'
10
+
11
+ #
12
+ # Apartment Configuration
13
+ #
14
+ Apartment.configure do |config|
15
+
16
+ # Add any models that you do not want to be multi-tenanted, but remain in the global (public) namespace.
17
+ # A typical example would be a Customer or Tenant model that stores each Tenant's information.
18
+ #
19
+ # config.excluded_models = %w{ Tenant }
20
+
21
+ # In order to migrate all of your Tenants you need to provide a list of Tenant names to Apartment.
22
+ # You can make this dynamic by providing a Proc object to be called on migrations.
23
+ # This object should yield either:
24
+ # - an array of strings representing each Tenant name.
25
+ # - a hash which keys are tenant names, and values custom db config (must contain all key/values required in database.yml)
26
+ #
27
+ # config.tenant_names = lambda{ Customer.pluck(:tenant_name) }
28
+ # config.tenant_names = ['tenant1', 'tenant2']
29
+ # config.tenant_names = {
30
+ # 'tenant1' => {
31
+ # adapter: 'postgresql',
32
+ # host: 'some_server',
33
+ # port: 5555,
34
+ # database: 'postgres' # this is not the name of the tenant's db
35
+ # # but the name of the database to connect to before creating the tenant's db
36
+ # # mandatory in postgresql
37
+ # },
38
+ # 'tenant2' => {
39
+ # adapter: 'postgresql',
40
+ # database: 'postgres' # this is not the name of the tenant's db
41
+ # # but the name of the database to connect to before creating the tenant's db
42
+ # # mandatory in postgresql
43
+ # }
44
+ # }
45
+ # config.tenant_names = lambda do
46
+ # Tenant.all.each_with_object({}) do |tenant, hash|
47
+ # hash[tenant.name] = tenant.db_configuration
48
+ # end
49
+ # end
50
+ #
51
+ config.tenant_names = lambda { ToDo_Tenant_Or_User_Model.pluck :database }
52
+
53
+ # PostgreSQL:
54
+ # Specifies whether to use PostgreSQL schemas or create a new database per Tenant.
55
+ #
56
+ # MySQL:
57
+ # Specifies whether to switch databases by using `use` statement or re-establish connection.
58
+ #
59
+ # The default behaviour is true.
60
+ #
61
+ # config.use_schemas = true
62
+
63
+ #
64
+ # ==> PostgreSQL only options
65
+
66
+ # Apartment can be forced to use raw SQL dumps instead of schema.rb for creating new schemas.
67
+ # Use this when you are using some extra features in PostgreSQL that can't be represented in
68
+ # schema.rb, like materialized views etc. (only applies with use_schemas set to true).
69
+ # (Note: this option doesn't use db/structure.sql, it creates SQL dump by executing pg_dump)
70
+ #
71
+ # config.use_sql = false
72
+
73
+ # There are cases where you might want some schemas to always be in your search_path
74
+ # e.g when using a PostgreSQL extension like hstore.
75
+ # Any schemas added here will be available along with your selected Tenant.
76
+ #
77
+ # config.persistent_schemas = %w{ hstore }
78
+
79
+ # <== PostgreSQL only options
80
+ #
81
+
82
+ # By default, and only when not using PostgreSQL schemas, Apartment will prepend the environment
83
+ # to the tenant name to ensure there is no conflict between your environments.
84
+ # This is mainly for the benefit of your development and test environments.
85
+ # Uncomment the line below if you want to disable this behaviour in production.
86
+ #
87
+ # config.prepend_environment = !Rails.env.production?
88
+
89
+ # When using PostgreSQL schemas, the database dump will be namespaced, and
90
+ # apartment will substitute the default namespace (usually public) with the
91
+ # name of the new tenant when creating a new tenant. Some items must maintain
92
+ # a reference to the default namespace (ie public) - for instance, a default
93
+ # uuid generation. Uncomment the line below to create a list of namespaced
94
+ # items in the schema dump that should *not* have their namespace replaced by
95
+ # the new tenant
96
+ #
97
+ # config.pg_excluded_names = ["uuid_generate_v4"]
98
+ end
99
+
100
+ # Setup a custom Tenant switching middleware. The Proc should return the name of the Tenant that
101
+ # you want to switch to.
102
+ # Rails.application.config.middleware.use Apartment::Elevators::Generic, lambda { |request|
103
+ # request.host.split('.').first
104
+ # }
105
+
106
+ # Rails.application.config.middleware.use Apartment::Elevators::Domain
107
+ Rails.application.config.middleware.use Apartment::Elevators::Subdomain
108
+ # Rails.application.config.middleware.use Apartment::Elevators::FirstSubdomain
109
+ # Rails.application.config.middleware.use Apartment::Elevators::Host