apartment 0.23.2 → 0.24.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/HISTORY.md +12 -1
- data/README.md +16 -13
- data/Rakefile +6 -1
- data/TODO.md +9 -14
- data/lib/apartment.rb +17 -3
- data/lib/apartment/adapters/abstract_adapter.rb +53 -44
- data/lib/apartment/adapters/jdbc_postgresql_adapter.rb +9 -9
- data/lib/apartment/adapters/mysql2_adapter.rb +15 -15
- data/lib/apartment/adapters/postgresql_adapter.rb +26 -18
- data/lib/apartment/adapters/sqlite3_adapter.rb +13 -13
- data/lib/apartment/database.rb +2 -2
- data/lib/apartment/elevators/host_hash.rb +3 -3
- data/lib/apartment/elevators/subdomain.rb +2 -3
- data/lib/apartment/migrator.rb +3 -3
- data/lib/apartment/railtie.rb +2 -1
- data/lib/apartment/tasks/enhancements.rb +26 -0
- data/lib/apartment/version.rb +1 -1
- data/lib/generators/apartment/install/templates/apartment.rb +13 -8
- data/lib/tasks/apartment.rake +34 -38
- data/spec/adapters/jdbc_mysql_adapter_spec.rb +2 -4
- data/spec/adapters/jdbc_postgresql_adapter_spec.rb +6 -6
- data/spec/adapters/mysql2_adapter_spec.rb +5 -5
- data/spec/adapters/postgresql_adapter_spec.rb +6 -6
- data/spec/adapters/sqlite3_adapter_spec.rb +2 -2
- data/spec/database_spec.rb +2 -2
- data/spec/dummy/config/initializers/apartment.rb +2 -2
- data/spec/examples/connection_adapter_examples.rb +2 -2
- data/spec/examples/generic_adapter_examples.rb +15 -15
- data/spec/examples/schema_adapter_examples.rb +6 -6
- data/spec/integration/apartment_rake_integration_spec.rb +4 -4
- data/spec/integration/query_caching_spec.rb +2 -2
- data/spec/support/requirements.rb +2 -5
- data/spec/tasks/apartment_rake_spec.rb +8 -9
- data/spec/unit/config_spec.rb +17 -10
- data/spec/unit/elevators/subdomain_spec.rb +26 -6
- metadata +3 -2
@@ -15,37 +15,37 @@ module Apartment
|
|
15
15
|
|
16
16
|
protected
|
17
17
|
|
18
|
-
# Connect to new
|
18
|
+
# Connect to new tenant
|
19
19
|
# Abstract adapter will catch generic ActiveRecord error
|
20
20
|
# Catch specific adapter errors here
|
21
21
|
#
|
22
|
-
# @param {String}
|
22
|
+
# @param {String} tenant Tenant name
|
23
23
|
#
|
24
|
-
def connect_to_new(
|
24
|
+
def connect_to_new(tenant = nil)
|
25
25
|
super
|
26
26
|
rescue Mysql2::Error
|
27
27
|
Apartment::Database.reset
|
28
|
-
raise DatabaseNotFound, "Cannot find
|
28
|
+
raise DatabaseNotFound, "Cannot find tenant #{environmentify(tenant)}"
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
class Mysql2SchemaAdapter < AbstractAdapter
|
33
|
-
attr_reader :
|
33
|
+
attr_reader :default_tenant
|
34
34
|
|
35
35
|
def initialize(config)
|
36
36
|
super
|
37
37
|
|
38
|
-
@
|
38
|
+
@default_tenant = config[:database]
|
39
39
|
reset
|
40
40
|
end
|
41
41
|
|
42
|
-
# Reset
|
42
|
+
# Reset current_tenant to the default_tenant
|
43
43
|
#
|
44
44
|
def reset
|
45
|
-
Apartment.connection.execute "use #{
|
45
|
+
Apartment.connection.execute "use #{default_tenant}"
|
46
46
|
end
|
47
47
|
|
48
|
-
# Set the table_name to always use the default
|
48
|
+
# Set the table_name to always use the default tenant for excluded models
|
49
49
|
#
|
50
50
|
def process_excluded_models
|
51
51
|
Apartment.excluded_models.each{ |model| process_excluded_model(model) }
|
@@ -53,16 +53,16 @@ module Apartment
|
|
53
53
|
|
54
54
|
protected
|
55
55
|
|
56
|
-
# Set schema
|
56
|
+
# Set schema current_tenant to new db
|
57
57
|
#
|
58
|
-
def connect_to_new(
|
59
|
-
return reset if
|
58
|
+
def connect_to_new(tenant)
|
59
|
+
return reset if tenant.nil?
|
60
60
|
|
61
|
-
Apartment.connection.execute "use #{environmentify(
|
61
|
+
Apartment.connection.execute "use #{environmentify(tenant)}"
|
62
62
|
|
63
63
|
rescue ActiveRecord::StatementInvalid
|
64
64
|
Apartment::Database.reset
|
65
|
-
raise DatabaseNotFound, "Cannot find
|
65
|
+
raise DatabaseNotFound, "Cannot find tenant #{environmentify(tenant)}"
|
66
66
|
end
|
67
67
|
|
68
68
|
def process_excluded_model(model)
|
@@ -74,7 +74,7 @@ module Apartment
|
|
74
74
|
# Ensure that if a schema *was* set, we override
|
75
75
|
table_name = klass.table_name.split('.', 2).last
|
76
76
|
|
77
|
-
klass.table_name = "#{
|
77
|
+
klass.table_name = "#{default_tenant}.#{table_name}"
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -14,6 +14,14 @@ module Apartment
|
|
14
14
|
# Default adapter when not using Postgresql Schemas
|
15
15
|
class PostgresqlAdapter < AbstractAdapter
|
16
16
|
|
17
|
+
def drop(tenant)
|
18
|
+
# Apartment.connection.drop_database note that drop_database will not throw an exception, so manually execute
|
19
|
+
Apartment.connection.execute(%{DROP DATABASE "#{tenant}"})
|
20
|
+
|
21
|
+
rescue *rescuable_exceptions
|
22
|
+
raise DatabaseNotFound, "The tenant #{tenant} cannot be found"
|
23
|
+
end
|
24
|
+
|
17
25
|
private
|
18
26
|
|
19
27
|
def rescue_from
|
@@ -30,15 +38,15 @@ module Apartment
|
|
30
38
|
reset
|
31
39
|
end
|
32
40
|
|
33
|
-
# Drop the
|
41
|
+
# Drop the tenant
|
34
42
|
#
|
35
|
-
# @param {String}
|
43
|
+
# @param {String} tenant Database (schema) to drop
|
36
44
|
#
|
37
|
-
def drop(
|
38
|
-
Apartment.connection.execute(%{DROP SCHEMA "#{
|
45
|
+
def drop(tenant)
|
46
|
+
Apartment.connection.execute(%{DROP SCHEMA "#{tenant}" CASCADE})
|
39
47
|
|
40
48
|
rescue *rescuable_exceptions
|
41
|
-
raise SchemaNotFound, "The schema #{
|
49
|
+
raise SchemaNotFound, "The schema #{tenant.inspect} cannot be found."
|
42
50
|
end
|
43
51
|
|
44
52
|
# Reset search path to default search_path
|
@@ -64,36 +72,36 @@ module Apartment
|
|
64
72
|
# @return {String} default schema search path
|
65
73
|
#
|
66
74
|
def reset
|
67
|
-
@
|
75
|
+
@current_tenant = Apartment.default_schema
|
68
76
|
Apartment.connection.schema_search_path = full_search_path
|
69
77
|
end
|
70
78
|
|
71
|
-
def
|
72
|
-
@
|
79
|
+
def current_tenant
|
80
|
+
@current_tenant || Apartment.default_schema
|
73
81
|
end
|
74
82
|
|
75
83
|
protected
|
76
84
|
|
77
85
|
# Set schema search path to new schema
|
78
86
|
#
|
79
|
-
def connect_to_new(
|
80
|
-
return reset if
|
81
|
-
raise ActiveRecord::StatementInvalid.new("Could not find schema #{
|
87
|
+
def connect_to_new(tenant = nil)
|
88
|
+
return reset if tenant.nil?
|
89
|
+
raise ActiveRecord::StatementInvalid.new("Could not find schema #{tenant}") unless Apartment.connection.schema_exists? tenant
|
82
90
|
|
83
|
-
@
|
91
|
+
@current_tenant = tenant.to_s
|
84
92
|
Apartment.connection.schema_search_path = full_search_path
|
85
93
|
|
86
94
|
rescue *rescuable_exceptions
|
87
|
-
raise SchemaNotFound, "One of the following schema(s) is invalid: #{
|
95
|
+
raise SchemaNotFound, "One of the following schema(s) is invalid: #{tenant}, #{full_search_path}"
|
88
96
|
end
|
89
97
|
|
90
98
|
# Create the new schema
|
91
99
|
#
|
92
|
-
def create_tenant(
|
93
|
-
Apartment.connection.execute(%{CREATE SCHEMA "#{
|
100
|
+
def create_tenant(tenant)
|
101
|
+
Apartment.connection.execute(%{CREATE SCHEMA "#{tenant}"})
|
94
102
|
|
95
103
|
rescue *rescuable_exceptions
|
96
|
-
raise SchemaExists, "The schema #{
|
104
|
+
raise SchemaExists, "The schema #{tenant} already exists."
|
97
105
|
end
|
98
106
|
|
99
107
|
private
|
@@ -103,9 +111,9 @@ module Apartment
|
|
103
111
|
def full_search_path
|
104
112
|
persistent_schemas.map(&:inspect).join(", ")
|
105
113
|
end
|
106
|
-
|
114
|
+
|
107
115
|
def persistent_schemas
|
108
|
-
[@
|
116
|
+
[@current_tenant, Apartment.persistent_schemas].flatten
|
109
117
|
end
|
110
118
|
end
|
111
119
|
end
|
@@ -15,38 +15,38 @@ module Apartment
|
|
15
15
|
super
|
16
16
|
end
|
17
17
|
|
18
|
-
def drop(
|
18
|
+
def drop(tenant)
|
19
19
|
raise DatabaseNotFound,
|
20
|
-
"The
|
20
|
+
"The tenant #{environmentify(tenant)} cannot be found." unless File.exists?(database_file(tenant))
|
21
21
|
|
22
|
-
File.delete(database_file(
|
22
|
+
File.delete(database_file(tenant))
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def current_tenant
|
26
26
|
File.basename(Apartment.connection.instance_variable_get(:@config)[:database], '.sqlite3')
|
27
27
|
end
|
28
28
|
|
29
29
|
protected
|
30
30
|
|
31
|
-
def connect_to_new(
|
31
|
+
def connect_to_new(tenant)
|
32
32
|
raise DatabaseNotFound,
|
33
|
-
"The
|
33
|
+
"The tenant #{environmentify(tenant)} cannot be found." unless File.exists?(database_file(tenant))
|
34
34
|
|
35
|
-
super database_file(
|
35
|
+
super database_file(tenant)
|
36
36
|
end
|
37
37
|
|
38
|
-
def create_tenant(
|
38
|
+
def create_tenant(tenant)
|
39
39
|
raise DatabaseExists,
|
40
|
-
"The
|
40
|
+
"The tenant #{environmentify(tenant)} already exists." if File.exists?(database_file(tenant))
|
41
41
|
|
42
|
-
f = File.new(database_file(
|
42
|
+
f = File.new(database_file(tenant), File::CREAT)
|
43
43
|
f.close
|
44
44
|
end
|
45
45
|
|
46
|
-
|
46
|
+
private
|
47
47
|
|
48
|
-
def database_file(
|
49
|
-
"#{@default_dir}/#{
|
48
|
+
def database_file(tenant)
|
49
|
+
"#{@default_dir}/#{tenant}.sqlite3"
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
data/lib/apartment/database.rb
CHANGED
@@ -8,7 +8,7 @@ module Apartment
|
|
8
8
|
extend self
|
9
9
|
extend Forwardable
|
10
10
|
|
11
|
-
def_delegators :adapter, :create, :
|
11
|
+
def_delegators :adapter, :create, :current_tenant, :current, :current_database, :drop, :process, :process_excluded_models, :reset, :seed, :switch
|
12
12
|
|
13
13
|
attr_writer :config
|
14
14
|
|
@@ -63,4 +63,4 @@ module Apartment
|
|
63
63
|
@config ||= Rails.configuration.database_configuration[Rails.env].symbolize_keys
|
64
64
|
end
|
65
65
|
end
|
66
|
-
end
|
66
|
+
end
|
@@ -2,8 +2,8 @@ require 'apartment/elevators/generic'
|
|
2
2
|
|
3
3
|
module Apartment
|
4
4
|
module Elevators
|
5
|
-
# Provides a rack based
|
6
|
-
# Uses a hash to find the corresponding
|
5
|
+
# Provides a rack based tenant switching solution based on hosts
|
6
|
+
# Uses a hash to find the corresponding tenant name for the host
|
7
7
|
#
|
8
8
|
class HostHash < Generic
|
9
9
|
def initialize(app, hash = {}, processor = nil)
|
@@ -13,7 +13,7 @@ module Apartment
|
|
13
13
|
|
14
14
|
def parse_tenant_name(request)
|
15
15
|
raise DatabaseNotFound,
|
16
|
-
"Cannot find
|
16
|
+
"Cannot find tenant for host #{request.host}" unless @hash.has_key?(request.host)
|
17
17
|
|
18
18
|
@hash[request.host]
|
19
19
|
end
|
@@ -37,11 +37,10 @@ module Apartment
|
|
37
37
|
subdomains(host).first
|
38
38
|
end
|
39
39
|
|
40
|
-
|
41
|
-
def subdomains(host, tld_length = 1)
|
40
|
+
def subdomains(host)
|
42
41
|
return [] unless named_host?(host)
|
43
42
|
|
44
|
-
host.split('.')[0..-(tld_length + 2)]
|
43
|
+
host.split('.')[0..-(Apartment.tld_length + 2)]
|
45
44
|
end
|
46
45
|
|
47
46
|
def named_host?(host)
|
data/lib/apartment/migrator.rb
CHANGED
@@ -10,7 +10,7 @@ module Apartment
|
|
10
10
|
Database.process(database) do
|
11
11
|
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
12
12
|
|
13
|
-
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.
|
13
|
+
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, version) do |migration|
|
14
14
|
ENV["SCOPE"].blank? || (ENV["SCOPE"] == migration.scope)
|
15
15
|
end
|
16
16
|
end
|
@@ -19,14 +19,14 @@ module Apartment
|
|
19
19
|
# Migrate up/down to a specific version
|
20
20
|
def run(direction, database, version)
|
21
21
|
Database.process(database) do
|
22
|
-
ActiveRecord::Migrator.run(direction, ActiveRecord::Migrator.
|
22
|
+
ActiveRecord::Migrator.run(direction, ActiveRecord::Migrator.migrations_paths, version)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
# rollback latest migration `step` number of times
|
27
27
|
def rollback(database, step = 1)
|
28
28
|
Database.process(database) do
|
29
|
-
ActiveRecord::Migrator.rollback(ActiveRecord::Migrator.
|
29
|
+
ActiveRecord::Migrator.rollback(ActiveRecord::Migrator.migrations_paths, step)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
data/lib/apartment/railtie.rb
CHANGED
@@ -13,10 +13,11 @@ module Apartment
|
|
13
13
|
Apartment.configure do |config|
|
14
14
|
config.excluded_models = []
|
15
15
|
config.use_schemas = true
|
16
|
-
config.
|
16
|
+
config.tenant_names = []
|
17
17
|
config.seed_after_create = false
|
18
18
|
config.prepend_environment = false
|
19
19
|
config.append_environment = false
|
20
|
+
config.tld_length = 1
|
20
21
|
end
|
21
22
|
|
22
23
|
ActiveRecord::Migrator.migrations_paths = Rails.application.paths['db/migrate'].to_a
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Require this file to append Apartment rake tasks to ActiveRecord db rake tasks
|
2
|
+
# Enabled by default in the initializer
|
3
|
+
|
4
|
+
Rake::Task["db:migrate"].enhance do
|
5
|
+
Rake::Task["apartment:migrate"].invoke
|
6
|
+
end
|
7
|
+
|
8
|
+
Rake::Task["db:rollback"].enhance do
|
9
|
+
Rake::Task["apartment:rollback"].invoke
|
10
|
+
end
|
11
|
+
|
12
|
+
Rake::Task["db:migrate:up"].enhance do
|
13
|
+
Rake::Task["apartment:migrate:up"].invoke
|
14
|
+
end
|
15
|
+
|
16
|
+
Rake::Task["db:migrate:down"].enhance do
|
17
|
+
Rake::Task["apartment:migrate:down"].invoke
|
18
|
+
end
|
19
|
+
|
20
|
+
Rake::Task["db:migrate:redo"].enhance do
|
21
|
+
Rake::Task["apartment:migrate:redo"].invoke
|
22
|
+
end
|
23
|
+
|
24
|
+
Rake::Task["db:seed"].enhance do
|
25
|
+
Rake::Task["apartment:seed"].invoke
|
26
|
+
end
|
data/lib/apartment/version.rb
CHANGED
@@ -9,13 +9,15 @@ require 'apartment/elevators/subdomain'
|
|
9
9
|
#
|
10
10
|
Apartment.configure do |config|
|
11
11
|
|
12
|
-
#
|
12
|
+
# These models will not be multi-tenanted,
|
13
13
|
# but remain in the global (public) namespace
|
14
|
-
#
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
}
|
14
|
+
#
|
15
|
+
# An example might be a Customer or Tenant model that stores each tenant information
|
16
|
+
# ex:
|
17
|
+
#
|
18
|
+
# config.excluded_models = %w{Tenant}
|
19
|
+
#
|
20
|
+
config.excluded_models = %w{}
|
19
21
|
|
20
22
|
# use postgres schemas?
|
21
23
|
config.use_schemas = true
|
@@ -28,8 +30,7 @@ Apartment.configure do |config|
|
|
28
30
|
# config.append_environment = true
|
29
31
|
|
30
32
|
# supply list of database names for migrations to run on
|
31
|
-
config.
|
32
|
-
|
33
|
+
config.tenant_names = lambda{ ToDo_Tenant_Or_User_Model.pluck :database }
|
33
34
|
end
|
34
35
|
|
35
36
|
##
|
@@ -42,3 +43,7 @@ end
|
|
42
43
|
# Rails.application.config.middleware.use 'Apartment::Elevators::Domain'
|
43
44
|
|
44
45
|
Rails.application.config.middleware.use 'Apartment::Elevators::Subdomain'
|
46
|
+
|
47
|
+
##
|
48
|
+
# Rake enhancements so that db:migrate etc... also runs migrations on all tenants
|
49
|
+
require 'apartment/tasks/enhancements'
|
data/lib/tasks/apartment.rake
CHANGED
@@ -2,38 +2,36 @@ require 'apartment/migrator'
|
|
2
2
|
|
3
3
|
apartment_namespace = namespace :apartment do
|
4
4
|
|
5
|
-
desc "Create all
|
6
|
-
task :
|
7
|
-
|
5
|
+
desc "Create all tenants"
|
6
|
+
task create: 'db:migrate' do
|
7
|
+
tenants.each do |tenant|
|
8
8
|
begin
|
9
|
-
puts("Creating #{
|
10
|
-
quietly { Apartment::Database.create(
|
9
|
+
puts("Creating #{tenant} tenant")
|
10
|
+
quietly { Apartment::Database.create(tenant) }
|
11
11
|
rescue Apartment::TenantExists => e
|
12
12
|
puts e.message
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
desc "Migrate all
|
18
|
-
task :migrate
|
19
|
-
|
20
|
-
database_names.each do |db|
|
17
|
+
desc "Migrate all tenants"
|
18
|
+
task :migrate do
|
19
|
+
tenants.each do |tenant|
|
21
20
|
begin
|
22
|
-
puts("Migrating #{
|
23
|
-
Apartment::Migrator.migrate
|
21
|
+
puts("Migrating #{tenant} tenant")
|
22
|
+
Apartment::Migrator.migrate tenant
|
24
23
|
rescue Apartment::TenantNotFound => e
|
25
24
|
puts e.message
|
26
25
|
end
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
|
-
desc "Seed all
|
31
|
-
task :seed
|
32
|
-
|
33
|
-
database_names.each do |db|
|
29
|
+
desc "Seed all tenants"
|
30
|
+
task :seed do
|
31
|
+
tenants.each do |tenant|
|
34
32
|
begin
|
35
|
-
puts("Seeding #{
|
36
|
-
Apartment::Database.process(
|
33
|
+
puts("Seeding #{tenant} tenant")
|
34
|
+
Apartment::Database.process(tenant) do
|
37
35
|
Apartment::Database.seed
|
38
36
|
end
|
39
37
|
rescue Apartment::TenantNotFound => e
|
@@ -42,14 +40,14 @@ apartment_namespace = namespace :apartment do
|
|
42
40
|
end
|
43
41
|
end
|
44
42
|
|
45
|
-
desc "Rolls the
|
46
|
-
task :rollback
|
43
|
+
desc "Rolls the migration back to the previous version (specify steps w/ STEP=n) across all tenants."
|
44
|
+
task :rollback do
|
47
45
|
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
|
48
46
|
|
49
|
-
|
47
|
+
tenants.each do |tenant|
|
50
48
|
begin
|
51
|
-
puts("Rolling back #{
|
52
|
-
Apartment::Migrator.rollback
|
49
|
+
puts("Rolling back #{tenant} tenant")
|
50
|
+
Apartment::Migrator.rollback tenant, step
|
53
51
|
rescue Apartment::TenantNotFound => e
|
54
52
|
puts e.message
|
55
53
|
end
|
@@ -57,39 +55,38 @@ apartment_namespace = namespace :apartment do
|
|
57
55
|
end
|
58
56
|
|
59
57
|
namespace :migrate do
|
60
|
-
|
61
|
-
|
62
|
-
task :up => 'db:migrate:up' do
|
58
|
+
desc 'Runs the "up" for a given migration VERSION across all tenants.'
|
59
|
+
task :up do
|
63
60
|
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
|
64
61
|
raise 'VERSION is required' unless version
|
65
62
|
|
66
|
-
|
63
|
+
tenants.each do |tenant|
|
67
64
|
begin
|
68
|
-
puts("Migrating #{
|
69
|
-
Apartment::Migrator.run :up,
|
65
|
+
puts("Migrating #{tenant} tenant up")
|
66
|
+
Apartment::Migrator.run :up, tenant, version
|
70
67
|
rescue Apartment::TenantNotFound => e
|
71
68
|
puts e.message
|
72
69
|
end
|
73
70
|
end
|
74
71
|
end
|
75
72
|
|
76
|
-
desc 'Runs the "down" for a given migration VERSION across all
|
77
|
-
task :down
|
73
|
+
desc 'Runs the "down" for a given migration VERSION across all tenants.'
|
74
|
+
task :down do
|
78
75
|
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
|
79
76
|
raise 'VERSION is required' unless version
|
80
77
|
|
81
|
-
|
78
|
+
tenants.each do |tenant|
|
82
79
|
begin
|
83
|
-
puts("Migrating #{
|
84
|
-
Apartment::Migrator.run :down,
|
80
|
+
puts("Migrating #{tenant} tenant down")
|
81
|
+
Apartment::Migrator.run :down, tenant, version
|
85
82
|
rescue Apartment::TenantNotFound => e
|
86
83
|
puts e.message
|
87
84
|
end
|
88
85
|
end
|
89
86
|
end
|
90
87
|
|
91
|
-
desc '
|
92
|
-
task :redo
|
88
|
+
desc 'Rolls back the tenant one migration and re migrate up (options: STEP=x, VERSION=x).'
|
89
|
+
task :redo do
|
93
90
|
if ENV['VERSION']
|
94
91
|
apartment_namespace['migrate:down'].invoke
|
95
92
|
apartment_namespace['migrate:up'].invoke
|
@@ -98,10 +95,9 @@ apartment_namespace = namespace :apartment do
|
|
98
95
|
apartment_namespace['migrate'].invoke
|
99
96
|
end
|
100
97
|
end
|
101
|
-
|
102
98
|
end
|
103
99
|
|
104
|
-
def
|
105
|
-
ENV['DB'] ? ENV['DB'].split(',').map { |s| s.strip } : Apartment.
|
100
|
+
def tenants
|
101
|
+
ENV['DB'] ? ENV['DB'].split(',').map { |s| s.strip } : Apartment.tenant_names
|
106
102
|
end
|
107
103
|
end
|