motel-activerecord 2.0.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1275f8eb347d61ff0aefb090f550154cfc2a3dc2
4
- data.tar.gz: 928c7506b87ec1057b9fbda06392729d1cbaab32
3
+ metadata.gz: a8adf465d12d86092aefa4034d84e91a680bebd2
4
+ data.tar.gz: 224ccbe7475d8faf3ce65b25797bd37a961feb0a
5
5
  SHA512:
6
- metadata.gz: fcb3abb6c7785374b284b03d96f33d0c13238fa1f8945c6134a1880291f3155735d42082e3de7e73c04f4b0aa9be5c460d6db8591336ab65e22d4b90a8bad629
7
- data.tar.gz: b1036fd084f60a19341df61f52fe6a2b86bb4adbb29c608a9c5fcae87a46b396d5fa79ef49723164d56f54fe1804ee005352808f8585336ab0083948e6a2cfb5
6
+ metadata.gz: eb426c11b7c6cb1c879d0a76154d3f9d2007436042a17ca70a7231b98f76a74873d08271ae159aa19270a3d32411f7ef4ec9a21d296b3e9b8ae909a5b4f7684d
7
+ data.tar.gz: 94926c8814e71010e05036f1df0aef1d665e425f154dc713e8ed16e47fa82e89f64b12c1dce092b1dd03fd930078043da674db096e025070f977eac624a040b9
data/README.md CHANGED
@@ -44,8 +44,8 @@ In your app/application.rb file write this:
44
44
  ```ruby
45
45
  config.motel.tenants_source_configurations = {
46
46
  source: :database,
47
- source_spec: { adapter: 'sqlite3', database: 'db/tenants.sqlite3' },
48
- table_name: 'tenant'
47
+ source_spec: { adapter: "sqlite3", database: "db/tenants.sqlite3" },
48
+ table_name: "tenant"
49
49
  }
50
50
  ```
51
51
 
@@ -53,13 +53,13 @@ You can specify the source by providing a hash of the
53
53
  connection specification. Example:
54
54
 
55
55
  ```ruby
56
- source_spec: {adapter: 'sqlite3', database: 'db/tenants.sqlite3'}
56
+ source_spec: { adapter: "sqlite3", database: "db/tenants.sqlite3" }
57
57
  ```
58
58
 
59
59
  Table name where are stored the connection details of tenants:
60
60
 
61
61
  ```ruby
62
- table_name: 'tenant'
62
+ table_name: "tenant"
63
63
  ```
64
64
 
65
65
  Note: The columns of the table must contain connection details and
@@ -88,7 +88,7 @@ config.motel.tenants_source_configurations = {
88
88
  source: :redis,
89
89
  host: 127.0.0.1,
90
90
  port: 6380,
91
- password: 'redis_password'
91
+ password: "redis_password"
92
92
  }
93
93
  ```
94
94
  To connect to Redis listening on a Unix socket, try use 'path'
@@ -102,7 +102,7 @@ If you want to assing dirently the tenants specificactions you can do it:
102
102
 
103
103
  ```ruby
104
104
  config.motel.tenants_source_configurations = {
105
- configurations: { 'foo' => { adapter: 'sqlite3', database: 'db/foo.sqlite3' }}
105
+ configurations: { "foo" => { adapter: "sqlite3", database: "db/foo.sqlite3" } }
106
106
  }
107
107
  ```
108
108
 
@@ -123,7 +123,7 @@ Set the `TENANT` environment variable to run the rake task on a
123
123
  specific tenant.
124
124
 
125
125
  ```ruby
126
- $ TENANT='foo' rake db:migrate
126
+ $ TENANT=foo rake db:migrate
127
127
  ```
128
128
 
129
129
  ### More configurations
@@ -131,7 +131,7 @@ $ TENANT='foo' rake db:migrate
131
131
  You can assign a default tenant if the current tenant is null:
132
132
 
133
133
  ```ruby
134
- config.motel.default_tenant = 'my_default_tenant'
134
+ config.motel.default_tenant = "my_default_tenant"
135
135
  ```
136
136
 
137
137
  Tenants switching is done via the subdomain of the url, you can
@@ -140,7 +140,7 @@ string. Example, to get the tenant `foo` from the follow url
140
140
  `http://www.example.com/foo/index` you should write:
141
141
 
142
142
  ```ruby
143
- config.motel.admission_criteria = '\/(\w*)\/'
143
+ config.motel.admission_criteria = "\/(\w*)\/"
144
144
  ```
145
145
 
146
146
  If you do not want the automatic switching of tenants by url you must
@@ -150,13 +150,6 @@ disable the middleware:
150
150
  config.motel.disable_middleware = true
151
151
  ```
152
152
 
153
- Path of the html page to show if tenant doesn't exist. Default is
154
- `public/404.html`.
155
-
156
- ```ruby
157
- config.motel.nonexistent_tenant_page = 'new_path'
158
- ```
159
-
160
153
  ## Use without Rails
161
154
 
162
155
  ### Specifying the source of tenants
@@ -167,11 +160,51 @@ use the method `tenants_source_configurations` of `Motel::Manager`:
167
160
  ```ruby
168
161
  Motel::Manager.tenants_source_configurations({
169
162
  source: :database,
170
- source_spec: { adapter: 'sqlite3', database: 'db/tenants.sqlite3' },
163
+ source_spec: { adapter: "sqlite3", database: "db/tenants.sqlite3" },
171
164
  table_name: 'tenant'
172
165
  })
173
166
  ```
174
167
 
168
+ # Usage
169
+
170
+ ## Switching tenants
171
+
172
+ If you're using Rails the tenant switching occurs automatically
173
+ through the Lobby middleware, otherwise you must set the current
174
+ tenant:
175
+
176
+ ```ruby
177
+ Motel::Manager.current_tenant = "foo"
178
+ ```
179
+
180
+ The switching of the tenant is not only based setting the variable
181
+ of the current tenant also by the environment variable or default
182
+ tenant. The hierarchy for tenant selection occurs in the following
183
+ order.
184
+
185
+ ```ruby
186
+ ENV["TENANT"] || Motel::Manager.current_tenant || Motel::Manager.default_tenant
187
+ ```
188
+
189
+ Usage example:
190
+
191
+ ```ruby
192
+ Motel::Manager.current_tenant = "foo"
193
+
194
+ FooBar.create(name: "Foo")
195
+ # => #<FooBar id: 1, name: "Foo">
196
+
197
+ Motel::Manager.current_tenant = "bar"
198
+
199
+ FooBar.all
200
+ # => #<ActiveRecord::Relation []>
201
+
202
+ Motel::Manager.current_tenant = "foo"
203
+
204
+ FooBar.all
205
+ # => #<ActiveRecord::Relation [#<FooBar id: 1, name: "Foo">]>
206
+ ```
207
+
175
208
  # Available methods
176
209
 
177
210
  Set a tenats source configurations
@@ -192,12 +225,6 @@ Set a default tenant
192
225
  Motel::Manager.default_tenant
193
226
  ```
194
227
 
195
- Set the html page to show if tenant doesn't exist
196
-
197
- ```ruby
198
- Motel::Manager.nonexistent_tenant_page
199
- ```
200
-
201
228
  Set a current tenant
202
229
 
203
230
  ```ruby
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.3
1
+ 2.1.0
@@ -1,10 +1,10 @@
1
- require 'motel/connection_adapters'
2
1
  require 'motel/lobby'
3
2
  require 'motel/manager'
4
3
  require 'motel/sources'
5
- require 'motel/multi_tenant'
6
4
  require 'motel/errors'
7
5
  require 'motel/version'
6
+ require 'motel/active_record'
7
+ require 'motel/connection_adapters'
8
8
 
9
9
  require 'motel/railtie' if defined? Rails
10
10
 
@@ -0,0 +1,4 @@
1
+ require 'motel/active_record/connection_handler'
2
+ require 'motel/active_record/migration'
3
+ require 'motel/active_record/query_cache'
4
+
@@ -0,0 +1,58 @@
1
+ require 'active_record'
2
+ require 'active_support/concern'
3
+ require 'motel/connection_adapters'
4
+
5
+ module Motel
6
+ module ActiveRecord
7
+ module ConnectionHandler
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+
12
+ self.default_connection_handler = Motel::ConnectionAdapters::ConnectionHandler.new
13
+
14
+ end
15
+
16
+ module ClassMethods
17
+
18
+ def establish_connection(config)
19
+ tenant_name = Motel::Manager.determines_tenant || self.name
20
+ resolver = Motel::ConnectionAdapters::ConnectionSpecification::Resolver.new
21
+ spec = resolver.spec(config)
22
+
23
+ connection_handler.establish_connection tenant_name, spec
24
+ end
25
+
26
+ def connection_pool
27
+ connection_handler.retrieve_connection_pool(current_tenant)
28
+ end
29
+
30
+ def retrieve_connection
31
+ connection_handler.retrieve_connection(current_tenant)
32
+ end
33
+
34
+ def connected?
35
+ connection_handler.connected?(current_tenant)
36
+ end
37
+
38
+ def remove_connection(tenant_name = current_tenant)
39
+ connection_handler.remove_connection(tenant_name)
40
+ end
41
+
42
+ def arel_engine
43
+ ::ActiveRecord::Base
44
+ end
45
+
46
+ def current_tenant
47
+ Motel::Manager.determines_tenant or raise Motel::NoCurrentTenantError
48
+ end
49
+
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ ActiveSupport.on_load(:active_record) do
56
+ include Motel::ActiveRecord::ConnectionHandler
57
+ end
58
+
@@ -0,0 +1,36 @@
1
+ require 'active_record'
2
+
3
+ module Motel
4
+ module ActiveRecord
5
+ module Migration
6
+ module CheckPending
7
+
8
+ def call(env)
9
+ return @app.call(env) unless Motel::Manager.determines_tenant
10
+
11
+ if connection.supports_migrations?
12
+ mtime = ::ActiveRecord::Migrator.last_migration.mtime.to_i
13
+ if @last_check < mtime
14
+ ::ActiveRecord::Migration.check_pending!(connection)
15
+ @last_check = mtime
16
+ end
17
+ end
18
+
19
+ @app.call(env)
20
+ end
21
+
22
+ private
23
+
24
+ def connection
25
+ ::ActiveRecord::Base.connection
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ class ActiveRecord::Migration::CheckPending
34
+ prepend Motel::ActiveRecord::Migration::CheckPending
35
+ end
36
+
@@ -0,0 +1,73 @@
1
+ require 'active_record'
2
+
3
+ module Motel
4
+ module ActiveRecord
5
+ module QueryCache
6
+
7
+ module ClassMethods
8
+
9
+ # Enable the query cache within the block if Active Record is configured.
10
+ # If it's not, it will execute the given block.
11
+ def cache(&block)
12
+ if Motel::Manager.determines_tenant &&
13
+ ::ActiveRecord::Base.connected?
14
+ connection.cache(&block)
15
+ else
16
+ yield
17
+ end
18
+ end
19
+
20
+ # Disable the query cache within the block if Active Record is configured.
21
+ # If it's not, it will execute the given block.
22
+ def uncached(&block)
23
+ if Motel::Manager.determines_tenant &&
24
+ ::ActiveRecord::Base.connected?
25
+ connection.uncached(&block)
26
+ else
27
+ yield
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ def call(env)
34
+ if Motel::Manager.determines_tenant
35
+ connection = ::ActiveRecord::Base.connection
36
+ enabled = connection.query_cache_enabled
37
+ connection_id = ::ActiveRecord::Base.connection_id
38
+ connection.enable_query_cache!
39
+
40
+ response = @app.call(env)
41
+ response[2] = Rack::BodyProxy.new(response[2]) do
42
+ restore_query_cache_settings(connection_id, enabled)
43
+ end
44
+
45
+ response
46
+ else
47
+ @app.call(env)
48
+ end
49
+ rescue Exception => e
50
+ if Motel::Manager.determines_tenant
51
+ restore_query_cache_settings(connection_id, enabled)
52
+ end
53
+
54
+ raise e
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+ end
61
+
62
+ class ::ActiveRecord::Base
63
+ extend Motel::ActiveRecord::QueryCache::ClassMethods
64
+ end
65
+
66
+ class ::ActiveRecord::QueryCache
67
+ prepend Motel::ActiveRecord::QueryCache
68
+ end
69
+
70
+ class ::ActiveRecord::ConnectionAdapters::AbstractAdapter
71
+ prepend Motel::ActiveRecord::QueryCache::ClassMethods
72
+ end
73
+
@@ -3,7 +3,7 @@ require 'active_record'
3
3
  module Motel
4
4
  module ConnectionAdapters
5
5
 
6
- class ConnectionHandler < ActiveRecord::ConnectionAdapters::ConnectionHandler
6
+ class ConnectionHandler < ::ActiveRecord::ConnectionAdapters::ConnectionHandler
7
7
 
8
8
  attr_accessor :tenants_source
9
9
 
@@ -21,7 +21,7 @@ module Motel
21
21
  def establish_connection(tenant_name, spec = nil)
22
22
  spec ||= connection_especification(tenant_name)
23
23
  @class_to_pool.clear
24
- owner_to_pool[tenant_name] = ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec)
24
+ owner_to_pool[tenant_name] = ::ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec)
25
25
  end
26
26
 
27
27
  def retrieve_connection(tenant_name)
@@ -82,8 +82,8 @@ module Motel
82
82
  resolver = ConnectionSpecification::Resolver.new
83
83
  spec = resolver.spec(tenants_source.tenant(tenant_name))
84
84
 
85
- unless ActiveRecord::Base.respond_to?(spec.adapter_method)
86
- raise ActiveRecord::AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
85
+ unless ::ActiveRecord::Base.respond_to?(spec.adapter_method)
86
+ raise ::ActiveRecord::AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
87
87
  end
88
88
 
89
89
  spec
@@ -16,7 +16,7 @@ module Motel
16
16
  def spec(config)
17
17
  spec = resolve(config).symbolize_keys
18
18
 
19
- raise(ActiveRecord::AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter)
19
+ raise(::ActiveRecord::AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter)
20
20
 
21
21
  path_to_adapter = "active_record/connection_adapters/#{spec[:adapter]}_adapter"
22
22
  begin
@@ -28,7 +28,7 @@ module Motel
28
28
  end
29
29
 
30
30
  adapter_method = "#{spec[:adapter]}_connection"
31
- ActiveRecord::ConnectionAdapters::ConnectionSpecification.new(spec, adapter_method)
31
+ ::ActiveRecord::ConnectionAdapters::ConnectionSpecification.new(spec, adapter_method)
32
32
  end
33
33
 
34
34
  private
@@ -36,7 +36,7 @@ module Motel
36
36
  def resolve(config)
37
37
  case config
38
38
  when nil
39
- raise ActiveRecord::AdapterNotSpecified
39
+ raise ::ActiveRecord::AdapterNotSpecified
40
40
  when String, Symbol
41
41
  resolve_string_connection config.to_s
42
42
  when Hash
data/lib/motel/lobby.rb CHANGED
@@ -10,23 +10,15 @@ module Motel
10
10
 
11
11
  def call(env)
12
12
  request = Rack::Request.new(env)
13
-
14
13
  name = tenant_name(request)
15
14
 
16
- if name
17
- if Motel::Manager.tenant?(name)
18
- Motel::Manager.current_tenant = name
19
- @app.call(env)
20
- else
21
- path = Motel::Manager.nonexistent_tenant_page
22
- file = File.expand_path(path) if path
23
- body = (File.exists?(file.to_s)) ? File.read(file) : "Nonexistent #{name} tenant"
24
- [404, {"Content-Type" => "text/html", "Content-Length" => body.size.to_s}, [body]]
25
- end
15
+ if name && Motel::Manager.tenant?(name)
16
+ Motel::Manager.current_tenant = name
26
17
  else
27
18
  Motel::Manager.current_tenant = nil
28
- @app.call(env)
29
19
  end
20
+
21
+ @app.call(env)
30
22
  end
31
23
 
32
24
  private
data/lib/motel/manager.rb CHANGED
@@ -5,10 +5,8 @@ require 'active_record'
5
5
  module Motel
6
6
  module Manager
7
7
 
8
- mattr_accessor :nonexistent_tenant_page
9
8
  mattr_accessor :admission_criteria
10
9
  mattr_accessor :default_tenant
11
- mattr_accessor :current_tenant
12
10
 
13
11
  class << self
14
12
 
@@ -18,7 +16,7 @@ module Motel
18
16
 
19
17
  source_instance = source_class.new(config)
20
18
 
21
- ActiveRecord::Base.connection_handler.tenants_source = source_instance
19
+ ::ActiveRecord::Base.connection_handler.tenants_source = source_instance
22
20
  end
23
21
 
24
22
  def tenants
@@ -39,19 +37,19 @@ module Motel
39
37
  end
40
38
 
41
39
  def update_tenant(name, spec)
42
- ActiveRecord::Base.remove_connection(name)
40
+ ::ActiveRecord::Base.remove_connection(name)
43
41
  tenants_source.update_tenant(name, spec)
44
42
  tenant(name)
45
43
  end
46
44
 
47
45
  def delete_tenant(name)
48
- ActiveRecord::Base.remove_connection(name)
46
+ ::ActiveRecord::Base.remove_connection(name)
49
47
  tenants_source.delete_tenant(name)
50
48
  !tenant?(name)
51
49
  end
52
50
 
53
51
  def active_tenants
54
- ActiveRecord::Base.connection_handler.active_tenants
52
+ ::ActiveRecord::Base.connection_handler.active_tenants
55
53
  end
56
54
 
57
55
  def determines_tenant
@@ -59,7 +57,25 @@ module Motel
59
57
  end
60
58
 
61
59
  def tenants_source
62
- ActiveRecord::Base.connection_handler.tenants_source
60
+ ::ActiveRecord::Base.connection_handler.tenants_source
61
+ end
62
+
63
+ def current_tenant=(tenant)
64
+ Thread.current.thread_variable_set(:@current_tenant, tenant)
65
+ end
66
+
67
+ def current_tenant
68
+ Thread.current.thread_variable_get(:@current_tenant)
69
+ end
70
+
71
+ def nonexistent_tenant_page=(path_page)
72
+ warn "[DEPRECATION] `nonexistent_tenant_page` is deprecated. The page is manage for ActionDispatch::DebugExceptions middleware."
73
+ @nonexistent_tenant_page = path_page
74
+ end
75
+
76
+ def nonexistent_tenant_page
77
+ warn "[DEPRECATION] `nonexistent_tenant_page` is deprecated. The page is manage for ActionDispatch::DebugExceptions middleware."
78
+ @nonexistent_tenant_page
63
79
  end
64
80
 
65
81
  end
data/lib/motel/railtie.rb CHANGED
@@ -9,6 +9,11 @@ module Motel
9
9
 
10
10
  config.motel = ActiveSupport::OrderedOptions.new
11
11
 
12
+ config.action_dispatch.rescue_responses.merge!(
13
+ 'Motel::NoCurrentTenantError' => :not_found,
14
+ 'Motel::NonexistentTenantError' => :not_found
15
+ )
16
+
12
17
  rake_tasks do
13
18
  namespace :db do
14
19
  task :load_config do
@@ -20,30 +25,30 @@ module Motel
20
25
  # retrieve the connection
21
26
  Motel::Manager.current_tenant ||= self.class
22
27
 
23
- ActiveRecord::Tasks::DatabaseTasks.database_configuration = Motel::Manager.tenants
24
- ActiveRecord::Base.configurations = ActiveRecord::Tasks::DatabaseTasks.database_configuration
25
- ActiveRecord::Tasks::DatabaseTasks.env = Motel::Manager.determines_tenant
28
+ ::ActiveRecord::Tasks::DatabaseTasks.database_configuration = Motel::Manager.tenants
29
+ ::ActiveRecord::Base.configurations = ::ActiveRecord::Tasks::DatabaseTasks.database_configuration
30
+ ::ActiveRecord::Tasks::DatabaseTasks.env = Motel::Manager.determines_tenant
26
31
  end
27
32
  end
28
33
  end
29
34
 
30
- ActiveRecord::Railtie.initializers.delete_if do |i|
35
+ ::ActiveRecord::Railtie.initializers.delete_if do |i|
31
36
  INIT_TO_DELETE.include?(i.name)
32
37
  end
33
38
 
34
39
  initializer "motel.general_configuration" do
35
40
  motel_config = Rails.application.config.motel
36
41
 
37
- Motel::Manager.nonexistent_tenant_page = motel_config.nonexistent_tenant_page || 'public/404.html'
42
+ Motel::Manager.nonexistent_tenant_page = motel_config.nonexistent_tenant_page || 'public/404.html' # Deprecated
38
43
  Motel::Manager.admission_criteria = motel_config.admission_criteria
39
44
  Motel::Manager.default_tenant = motel_config.default_tenant
40
- Motel::Manager.current_tenant = motel_config.current_tenant
41
45
  Motel::Manager.tenants_source_configurations(motel_config.tenants_source_configurations)
42
46
  end
43
47
 
48
+ # Set lobby middleware before all ActiveRecord's middlewares
44
49
  initializer "motel.configure_middleware" do |app|
45
50
  if !Rails.application.config.motel.disable_middleware && (Rails.env != 'test')
46
- app.config.middleware.insert_before ActiveRecord::Migration::CheckPending, Lobby
51
+ app.config.middleware.insert_after ActionDispatch::Callbacks, Lobby
47
52
  end
48
53
  end
49
54
 
@@ -52,10 +57,10 @@ module Motel
52
57
 
53
58
  ActiveSupport.on_load(:active_record) do
54
59
  ActionDispatch::Reloader.send(hook) do
55
- ActiveRecord::Base.clear_reloadable_connections!
60
+ ::ActiveRecord::Base.clear_reloadable_connections!
56
61
  # Clear cache of the current tenant with an active connection
57
62
  if Motel::Manager.active_tenants.include?(Motel::Manager.determines_tenant)
58
- ActiveRecord::Base.clear_cache!
63
+ ::ActiveRecord::Base.clear_cache!
59
64
  end
60
65
  end
61
66
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ActiveRecord::Base do
3
+ describe ::ActiveRecord::Base do
4
4
 
5
5
  before(:all) do
6
6
  Motel::Manager.tenants_source_configurations({source: :default})
@@ -14,8 +14,8 @@ describe ActiveRecord::Base do
14
14
  end
15
15
 
16
16
  after(:each) do
17
- ActiveRecord::Base.connection_handler.active_tenants do |tenant|
18
- ActiveRecord::Base.connection_handler.remove_connection(tenant)
17
+ ::ActiveRecord::Base.connection_handler.active_tenants do |tenant|
18
+ ::ActiveRecord::Base.connection_handler.remove_connection(tenant)
19
19
  end
20
20
  Motel::Manager.current_tenant = nil
21
21
  end
@@ -29,9 +29,9 @@ describe ActiveRecord::Base do
29
29
  end
30
30
 
31
31
  it 'establishes a connection keyed by tenant name' do
32
- ActiveRecord::Base.establish_connection(FOO_SPEC)
32
+ ::ActiveRecord::Base.establish_connection(FOO_SPEC)
33
33
 
34
- expect(ActiveRecord::Base.connection_handler.active_tenants).to include('foo')
34
+ expect(::ActiveRecord::Base.connection_handler.active_tenants).to include('foo')
35
35
  end
36
36
 
37
37
  end
@@ -39,9 +39,9 @@ describe ActiveRecord::Base do
39
39
  context 'without setting the current tenant name' do
40
40
 
41
41
  it 'establishes a connection keyed by class name' do
42
- ActiveRecord::Base.establish_connection(BAZ_SPEC)
42
+ ::ActiveRecord::Base.establish_connection(BAZ_SPEC)
43
43
 
44
- expect(ActiveRecord::Base.connection_handler.active_tenants).to include('ActiveRecord::Base')
44
+ expect(::ActiveRecord::Base.connection_handler.active_tenants).to include('ActiveRecord::Base')
45
45
  end
46
46
 
47
47
  end
@@ -54,9 +54,9 @@ describe ActiveRecord::Base do
54
54
 
55
55
  it 'returns a connection pool of current tenant' do
56
56
  Motel::Manager.current_tenant = 'foo'
57
- pool = ActiveRecord::Base.connection_handler.establish_connection('foo')
57
+ pool = ::ActiveRecord::Base.connection_handler.establish_connection('foo')
58
58
 
59
- expect(ActiveRecord::Base.connection_pool).to eq pool
59
+ expect(::ActiveRecord::Base.connection_pool).to eq pool
60
60
  end
61
61
 
62
62
  end
@@ -65,7 +65,7 @@ describe ActiveRecord::Base do
65
65
 
66
66
  it 'rises an error' do
67
67
  Motel::Manager.current_tenant = nil
68
- expect{ActiveRecord::Base.connection_pool}.to raise_error Motel::NoCurrentTenantError
68
+ expect{::ActiveRecord::Base.connection_pool}.to raise_error Motel::NoCurrentTenantError
69
69
  end
70
70
 
71
71
  end
@@ -78,9 +78,9 @@ describe ActiveRecord::Base do
78
78
 
79
79
  it 'returns a connection of current tenant' do
80
80
  Motel::Manager.current_tenant = 'foo'
81
- pool = ActiveRecord::Base.connection_handler.establish_connection('foo')
81
+ pool = ::ActiveRecord::Base.connection_handler.establish_connection('foo')
82
82
 
83
- expect(ActiveRecord::Base.retrieve_connection).to eq pool.connection
83
+ expect(::ActiveRecord::Base.retrieve_connection).to eq pool.connection
84
84
  end
85
85
 
86
86
  end
@@ -89,7 +89,7 @@ describe ActiveRecord::Base do
89
89
 
90
90
  it 'rises an error' do
91
91
  Motel::Manager.current_tenant = nil
92
- expect{ActiveRecord::Base.retrieve_connection}.to raise_error Motel::NoCurrentTenantError
92
+ expect{::ActiveRecord::Base.retrieve_connection}.to raise_error Motel::NoCurrentTenantError
93
93
  end
94
94
 
95
95
  end
@@ -99,19 +99,19 @@ describe ActiveRecord::Base do
99
99
  describe '.connected?' do
100
100
 
101
101
  before(:each) do
102
- ActiveRecord::Base.connection_handler.retrieve_connection('foo')
102
+ ::ActiveRecord::Base.connection_handler.retrieve_connection('foo')
103
103
  end
104
104
 
105
105
  context 'current tenant established' do
106
106
 
107
107
  it 'returns true' do
108
108
  Motel::Manager.current_tenant = 'foo'
109
- expect(ActiveRecord::Base.connected?).to be_truthy
109
+ expect(::ActiveRecord::Base.connected?).to be_truthy
110
110
  end
111
111
 
112
112
  it 'returns false' do
113
113
  Motel::Manager.current_tenant = 'bar'
114
- expect(ActiveRecord::Base.connected?).to be_falsey
114
+ expect(::ActiveRecord::Base.connected?).to be_falsey
115
115
  end
116
116
 
117
117
  end
@@ -120,7 +120,7 @@ describe ActiveRecord::Base do
120
120
 
121
121
  it 'rises an error' do
122
122
  Motel::Manager.current_tenant = nil
123
- expect{ActiveRecord::Base.connected?}.to raise_error Motel::NoCurrentTenantError
123
+ expect{::ActiveRecord::Base.connected?}.to raise_error Motel::NoCurrentTenantError
124
124
  end
125
125
 
126
126
  end
@@ -132,10 +132,10 @@ describe ActiveRecord::Base do
132
132
  context 'current tenant established' do
133
133
 
134
134
  it 'removes connection' do
135
- ActiveRecord::Base.connection_handler.establish_connection('foo')
135
+ ::ActiveRecord::Base.connection_handler.establish_connection('foo')
136
136
  Motel::Manager.current_tenant = 'foo'
137
- ActiveRecord::Base.remove_connection
138
- expect(ActiveRecord::Base.connection_handler.active_tenants).not_to include('foo')
137
+ ::ActiveRecord::Base.remove_connection
138
+ expect(::ActiveRecord::Base.connection_handler.active_tenants).not_to include('foo')
139
139
  end
140
140
 
141
141
  end
@@ -144,7 +144,7 @@ describe ActiveRecord::Base do
144
144
 
145
145
  it 'rises an error' do
146
146
  Motel::Manager.current_tenant = nil
147
- expect{ActiveRecord::Base.remove_connection}.to raise_error Motel::NoCurrentTenantError
147
+ expect{::ActiveRecord::Base.remove_connection}.to raise_error Motel::NoCurrentTenantError
148
148
  end
149
149
 
150
150
  end
@@ -154,7 +154,7 @@ describe ActiveRecord::Base do
154
154
  describe '.arel_engine' do
155
155
 
156
156
  it 'returns a ActiveRecord::Base class' do
157
- expect(ActiveRecord::Base.arel_engine).to eq ActiveRecord::Base
157
+ expect(::ActiveRecord::Base.arel_engine).to eq ::ActiveRecord::Base
158
158
  end
159
159
 
160
160
  end
@@ -166,7 +166,7 @@ describe ActiveRecord::Base do
166
166
  it 'returns the current tenant' do
167
167
  Motel::Manager.current_tenant = 'foo'
168
168
 
169
- expect(ActiveRecord::Base.current_tenant).to eq 'foo'
169
+ expect(::ActiveRecord::Base.current_tenant).to eq 'foo'
170
170
  end
171
171
 
172
172
  end
@@ -176,7 +176,7 @@ describe ActiveRecord::Base do
176
176
  it 'rises an error' do
177
177
  Motel::Manager.current_tenant = nil
178
178
 
179
- expect{ActiveRecord::Base.current_tenant}.to raise_error Motel::NoCurrentTenantError
179
+ expect{::ActiveRecord::Base.current_tenant}.to raise_error Motel::NoCurrentTenantError
180
180
  end
181
181
 
182
182
  end
@@ -19,7 +19,6 @@ describe Motel::Lobby do
19
19
  after(:all) do
20
20
  Motel::Manager.delete_tenant('foo')
21
21
  Motel::Manager.admission_criteria = nil #sets default
22
- Motel::Manager.nonexistent_tenant_page = nil #sets default
23
22
  end
24
23
 
25
24
  describe '#call' do
@@ -58,37 +57,16 @@ describe Motel::Lobby do
58
57
  @url = 'http://bar.test.com'
59
58
  end
60
59
 
61
- it 'returns 404 code' do
60
+ it 'sets the current tenant on nil' do
62
61
  request @url
63
62
 
64
- expect(last_response.status).to eq 404
63
+ expect(Motel::Manager.current_tenant).to be_nil
65
64
  end
66
65
 
67
- context 'with default nonexistent tenant message' do
68
-
69
- it 'returns default message on body' do
70
- Motel::Manager.nonexistent_tenant_page = nil
71
- request @url
72
-
73
- expect(last_response.body).to eq "Nonexistent bar tenant"
74
- end
75
-
76
- end
77
-
78
- context 'specifying the path of the page with the nonexistent tenant message' do
79
-
80
- it 'returns default message on body' do
81
- message = '<h1>Noexistent tenant<h1>'
82
- file = Tempfile.new(['status_404', '.html'], TEMP_DIR)
83
- file.write(message)
84
- file.close
85
-
86
- Motel::Manager.nonexistent_tenant_page = file.path
87
- request @url
88
-
89
- expect(last_response.body).to eq message
90
- end
66
+ it 'response is ok' do
67
+ request @url
91
68
 
69
+ expect(last_response).to be_ok
92
70
  end
93
71
 
94
72
  end
@@ -3,17 +3,17 @@ require 'spec_helper'
3
3
  describe Motel::Manager do
4
4
 
5
5
  before(:all) do
6
- ActiveRecord::Base.connection_handler = begin
6
+ ::ActiveRecord::Base.connection_handler = begin
7
7
  Motel::ConnectionAdapters::ConnectionHandler.new
8
8
  end
9
9
  @manager = Motel::Manager
10
10
  end
11
11
 
12
12
  before(:each) do
13
- ActiveRecord::Base.connection_handler.tenants_source = begin
13
+ ::ActiveRecord::Base.connection_handler.tenants_source = begin
14
14
  Motel::Sources::Default.new
15
15
  end
16
- @tenants_source = ActiveRecord::Base.connection_handler.tenants_source
16
+ @tenants_source = ::ActiveRecord::Base.connection_handler.tenants_source
17
17
  @tenants_source.add_tenant('foo', FOO_SPEC)
18
18
  @tenants_source.add_tenant('bar', BAR_SPEC)
19
19
  end
@@ -24,8 +24,8 @@ describe Motel::Manager do
24
24
  @manager.default_tenant = nil
25
25
 
26
26
  # Remove all connections tenant
27
- ActiveRecord::Base.connection_handler.active_tenants do |tenant|
28
- ActiveRecord::Base.connection_handler.remove_connection(tenant)
27
+ ::ActiveRecord::Base.connection_handler.active_tenants do |tenant|
28
+ ::ActiveRecord::Base.connection_handler.remove_connection(tenant)
29
29
  end
30
30
  end
31
31
 
@@ -123,7 +123,7 @@ describe Motel::Manager do
123
123
  it 'returns true if tenant baz does exist' do
124
124
  resolver = Motel::ConnectionAdapters::ConnectionSpecification::Resolver.new
125
125
  spec = resolver.spec(BAZ_SPEC)
126
- handler = ActiveRecord::Base.connection_handler
126
+ handler = ::ActiveRecord::Base.connection_handler
127
127
  handler.establish_connection('baz', spec)
128
128
  expect(@manager.tenant?('baz')).to be_truthy
129
129
  end
@@ -176,10 +176,10 @@ describe Motel::Manager do
176
176
 
177
177
  it 'removes connection of tenant' do
178
178
 
179
- ActiveRecord::Base.connection_handler.establish_connection('foo')
179
+ ::ActiveRecord::Base.connection_handler.establish_connection('foo')
180
180
  @manager.delete_tenant('foo')
181
181
 
182
- expect(ActiveRecord::Base.connection_handler.active_tenants).not_to include('foo')
182
+ expect(::ActiveRecord::Base.connection_handler.active_tenants).not_to include('foo')
183
183
  end
184
184
 
185
185
  end
@@ -187,7 +187,7 @@ describe Motel::Manager do
187
187
  describe '#active_tenants' do
188
188
 
189
189
  it 'returns active tenans' do
190
- ActiveRecord::Base.connection_handler.establish_connection('foo')
190
+ ::ActiveRecord::Base.connection_handler.establish_connection('foo')
191
191
  expect(@manager.active_tenants).to include('foo')
192
192
  end
193
193
 
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Motel::Sources::Database do
4
4
 
5
5
  before(:all) do
6
- @klass = Class.new(ActiveRecord::Base) { def self.name; 'klass'; end }
6
+ @klass = Class.new(::ActiveRecord::Base) { def self.name; 'klass'; end }
7
7
 
8
8
  resolver = Motel::ConnectionAdapters::ConnectionSpecification::Resolver.new
9
9
  @handler = Motel::ConnectionAdapters::ConnectionHandler.new
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motel-activerecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Diego Martínez Valdelamar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-17 00:00:00.000000000 Z
11
+ date: 2014-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
54
  version: 3.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rspec
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,20 @@ dependencies:
80
94
  - - ~>
81
95
  - !ruby/object:Gem::Version
82
96
  version: '1.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rack-test
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  description: ActiveRecord extension to use connections to multiple databases
84
112
  email: dimarva.90@gmail.com
85
113
  executables: []
@@ -93,14 +121,17 @@ files:
93
121
  - lib/motel/sources/database.rb
94
122
  - lib/motel/sources/default.rb
95
123
  - lib/motel/sources/redis.rb
124
+ - lib/motel/active_record.rb
96
125
  - lib/motel/errors.rb
97
126
  - lib/motel/version.rb
98
127
  - lib/motel/connection_adapters.rb
99
- - lib/motel/multi_tenant.rb
100
128
  - lib/motel/connection_adapters/connection_specification/resolver.rb
101
129
  - lib/motel/connection_adapters/connection_specification.rb
102
130
  - lib/motel/connection_adapters/connection_handler.rb
103
131
  - lib/motel/lobby.rb
132
+ - lib/motel/active_record/query_cache.rb
133
+ - lib/motel/active_record/migration.rb
134
+ - lib/motel/active_record/connection_handler.rb
104
135
  - VERSION
105
136
  - README.md
106
137
  - spec/tmp/foo.sqlite3
@@ -111,9 +142,9 @@ files:
111
142
  - spec/lib/motel/sources/redis_spec.rb
112
143
  - spec/lib/motel/connection_adapters/connection_specification/resolver_spec.rb
113
144
  - spec/lib/motel/connection_adapters/connection_handler_spec.rb
114
- - spec/lib/motel/multi_tenant_spec.rb
115
145
  - spec/lib/motel/lobby_spec.rb
116
146
  - spec/lib/motel/manager_spec.rb
147
+ - spec/lib/motel/active_record/connection_handler.rb
117
148
  homepage: https://github.com/dimarval/motel-activerecord
118
149
  licenses:
119
150
  - MIT
@@ -147,7 +178,7 @@ test_files:
147
178
  - spec/lib/motel/sources/redis_spec.rb
148
179
  - spec/lib/motel/connection_adapters/connection_specification/resolver_spec.rb
149
180
  - spec/lib/motel/connection_adapters/connection_handler_spec.rb
150
- - spec/lib/motel/multi_tenant_spec.rb
151
181
  - spec/lib/motel/lobby_spec.rb
152
182
  - spec/lib/motel/manager_spec.rb
183
+ - spec/lib/motel/active_record/connection_handler.rb
153
184
  has_rdoc:
@@ -1,53 +0,0 @@
1
- module Motel
2
- module MultiTenant
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
-
7
- self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
8
-
9
- end
10
-
11
- module ClassMethods
12
-
13
- def establish_connection(config)
14
- tenant_name = Motel::Manager.determines_tenant || self.name
15
- resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new
16
- spec = resolver.spec(config)
17
-
18
- connection_handler.establish_connection tenant_name, spec
19
- end
20
-
21
- def connection_pool
22
- connection_handler.retrieve_connection_pool(current_tenant)
23
- end
24
-
25
- def retrieve_connection
26
- connection_handler.retrieve_connection(current_tenant)
27
- end
28
-
29
- def connected?
30
- connection_handler.connected?(current_tenant)
31
- end
32
-
33
- def remove_connection(tenant_name = current_tenant)
34
- connection_handler.remove_connection(tenant_name)
35
- end
36
-
37
- def arel_engine
38
- ActiveRecord::Base
39
- end
40
-
41
- def current_tenant
42
- Motel::Manager.determines_tenant or raise Motel::NoCurrentTenantError
43
- end
44
-
45
- end
46
- end
47
-
48
- end
49
-
50
- ActiveSupport.on_load(:active_record) do
51
- include Motel::MultiTenant
52
- end
53
-