acts_as_tenant 0.4.4 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +86 -25
- data/Rakefile +5 -3
- data/lib/acts_as_tenant.rb +112 -14
- data/lib/acts_as_tenant/configuration.rb +6 -19
- data/lib/acts_as_tenant/controller_extensions.rb +10 -59
- data/lib/acts_as_tenant/controller_extensions/filter.rb +13 -0
- data/lib/acts_as_tenant/controller_extensions/subdomain.rb +20 -0
- data/lib/acts_as_tenant/controller_extensions/subdomain_or_domain.rb +20 -0
- data/lib/acts_as_tenant/errors.rb +3 -4
- data/lib/acts_as_tenant/model_extensions.rb +33 -136
- data/lib/acts_as_tenant/sidekiq.rb +11 -7
- data/lib/acts_as_tenant/tenant_helper.rb +7 -0
- data/lib/acts_as_tenant/test_tenant_middleware.rb +15 -0
- data/lib/acts_as_tenant/version.rb +1 -1
- data/spec/acts_as_tenant/configuration_spec.rb +8 -19
- data/spec/acts_as_tenant/sidekiq_spec.rb +14 -19
- data/spec/{acts_as_tenant/tenant_by_filter_spec.rb → controllers/filter_spec.rb} +7 -12
- data/spec/controllers/subdomain_or_domain_spec.rb +55 -0
- data/spec/controllers/subdomain_spec.rb +49 -0
- data/spec/dummy/.ruby-version +1 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +2 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/javascript/packs/application.js +15 -0
- data/spec/dummy/app/jobs/application_job.rb +7 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/mailers/user_mailer.rb +5 -0
- data/spec/dummy/app/models/account.rb +4 -0
- data/spec/dummy/app/models/aliased_task.rb +4 -0
- data/spec/dummy/app/models/article.rb +3 -0
- data/spec/dummy/app/models/comment.rb +5 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/custom_counter_cache_task.rb +4 -0
- data/spec/dummy/app/models/custom_foreign_key_task.rb +4 -0
- data/spec/dummy/app/models/custom_primary_key_task.rb +4 -0
- data/spec/dummy/app/models/global_project.rb +6 -0
- data/spec/dummy/app/models/manager.rb +4 -0
- data/spec/dummy/app/models/polymorphic_tenant_comment.rb +5 -0
- data/spec/dummy/app/models/project.rb +8 -0
- data/spec/dummy/app/models/task.rb +7 -0
- data/spec/dummy/app/models/unique_task.rb +5 -0
- data/spec/dummy/app/models/unscoped_model.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +33 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +19 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +19 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +62 -0
- data/spec/dummy/config/environments/production.rb +112 -0
- data/spec/dummy/config/environments/test.rb +49 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/assets.rb +12 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +40 -0
- data/spec/dummy/config/puma.rb +38 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/db/schema.rb +84 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/development_secret.txt +1 -0
- data/spec/fixtures/accounts.yml +10 -0
- data/spec/fixtures/custom_primary_key_tasks.yml +2 -0
- data/spec/fixtures/global_projects.yml +13 -0
- data/spec/fixtures/projects.yml +10 -0
- data/spec/helpers/tenant_helper_spec.rb +16 -0
- data/spec/middlewares/test_tenant_middleware_spec.rb +86 -0
- data/spec/models/model_extensions_spec.rb +383 -0
- data/spec/spec_helper.rb +9 -13
- metadata +201 -41
- data/.gitignore +0 -7
- data/.travis.yml +0 -4
- data/CHANGELOG.md +0 -119
- data/Gemfile +0 -4
- data/_config.yml +0 -1
- data/acts_as_tenant.gemspec +0 -32
- data/docs/blog_post.md +0 -67
- data/rails/init.rb +0 -2
- data/spec/active_record_helper.rb +0 -22
- data/spec/active_record_models.rb +0 -143
- data/spec/acts_as_tenant/model_extensions_spec.rb +0 -476
- data/spec/acts_as_tenant/tenant_by_subdomain_or_domain.rb +0 -46
- data/spec/acts_as_tenant/tenant_by_subdomain_spec.rb +0 -32
- data/spec/database.yml +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fda1a0075313a96256ff1815cf9fd08422e2cfd18934703e8325273b2b941a3e
|
4
|
+
data.tar.gz: e89bef1337f0210769a0ffaca7c081a111944bdbdb5b4d282118df39f4a1d53f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b80f8de28ae30db10fdca8e9a2a290e014c87ab195b250661c4c81a7d33d761b67929b2b43f77380c3c5fbe128611ede07e135c7adc3708f9fbe406d1f7e8516
|
7
|
+
data.tar.gz: ec85db56efcd7441559ef33adbc0ec25bd366108aa3bd2da9f1bd3279776e45181e9153796d2071116991c63a76e849b1411d8d852c4ba25fb0497958a59192a
|
data/README.md
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
Acts As Tenant
|
2
2
|
==============
|
3
3
|
|
4
|
-
[![Build Status](https://
|
5
|
-
|
6
|
-
**Note**: acts_as_tenant was introduced in this [blog post](https://github.com/ErwinM/acts_as_tenant/blob/master/docs/blog_post.md).
|
4
|
+
[![Build Status](https://github.com/ErwinM/acts_as_tenant/workflows/Tests/badge.svg)](https://github.com/ErwinM/acts_as_tenant/actions)
|
7
5
|
|
8
6
|
This gem was born out of our own need for a fail-safe and out-of-the-way manner to add multi-tenancy to our Rails app through a shared database strategy, that integrates (near) seamless with Rails.
|
9
7
|
|
@@ -16,6 +14,8 @@ In addition, acts_as_tenant:
|
|
16
14
|
* adds a method to validate uniqueness to a tenant, `validates_uniqueness_to_tenant`
|
17
15
|
* sets up a helper method containing the current tenant
|
18
16
|
|
17
|
+
**Note**: acts_as_tenant was introduced in this [blog post](https://github.com/ErwinM/acts_as_tenant/blob/master/docs/blog_post.md).
|
18
|
+
|
19
19
|
Installation
|
20
20
|
------------
|
21
21
|
acts_as_tenant will only work on Rails 3.1 and up. This is due to changes made to the handling of `default_scope`, an essential pillar of the gem.
|
@@ -41,7 +41,8 @@ There are three ways to set the current tenant:
|
|
41
41
|
2. by setting the current tenant in the controller, and
|
42
42
|
3. by setting the current tenant for a block.
|
43
43
|
|
44
|
-
###
|
44
|
+
### Looking Up Tenants
|
45
|
+
#### By Subdomain to lookup the current tenant
|
45
46
|
|
46
47
|
```ruby
|
47
48
|
class ApplicationController < ActionController::Base
|
@@ -49,11 +50,23 @@ class ApplicationController < ActionController::Base
|
|
49
50
|
end
|
50
51
|
```
|
51
52
|
|
52
|
-
This tells acts_as_tenant to use the
|
53
|
+
This tells acts_as_tenant to use the last subdomain to identify the current tenant. In addition, it tells acts_as_tenant that tenants are represented by the Account model and this model has a column named 'subdomain' which can be used to lookup the Account using the actual subdomain. If ommitted, the parameters will default to the values used above.
|
54
|
+
|
55
|
+
By default, the *last* subdomain will be used for lookup. Pass in `subdomain_lookup: :first` to use the first subdomain instead.
|
56
|
+
|
57
|
+
#### By Domain to lookup the current tenant
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
class ApplicationController < ActionController::Base
|
61
|
+
set_current_tenant_by_subdomain_or_domain(:account, :subdomain, :domain)
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
You can locate the tenant using `set_current_tenant_by_subdomain_or_domain( :account, :subdomain, :domain )` which will check for a subdomain and fallback to domain.
|
53
66
|
|
54
|
-
|
67
|
+
By default, the *last* subdomain will be used for lookup. Pass in `subdomain_lookup: :first` to use the first subdomain instead.
|
55
68
|
|
56
|
-
|
69
|
+
#### Manually using before_action
|
57
70
|
|
58
71
|
```ruby
|
59
72
|
class ApplicationController < ActionController::Base
|
@@ -69,6 +82,21 @@ end
|
|
69
82
|
|
70
83
|
Setting the `current_tenant` yourself, requires you to declare `set_current_tenant_through_filter` at the top of your application_controller to tell acts_as_tenant that you are going to use a before_action to setup the current tenant. Next you should actually setup that before_action to fetch the current tenant and pass it to `acts_as_tenant` by using `set_current_tenant(current_tenant)` in the before_action.
|
71
84
|
|
85
|
+
If you are setting the tenant in a specific controller (except `application_controller`), it should to be included **AT THE TOP** of the file.
|
86
|
+
|
87
|
+
```
|
88
|
+
class MembersController < ActionController::Base
|
89
|
+
set_current_tenant_through_filter
|
90
|
+
before_action :set_tenant
|
91
|
+
before_action :set_member, only: [:show, :edit, :update, :destroy]
|
92
|
+
|
93
|
+
def set_tenant
|
94
|
+
set_current_tenant(current_user.account)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
This allows the tenant to be set before any other code runs so everything is within the current tenant.
|
72
100
|
|
73
101
|
### Setting the current tenant for a block ###
|
74
102
|
|
@@ -151,10 +179,18 @@ All options available to Rails' own `validates_uniqueness_of` are also available
|
|
151
179
|
|
152
180
|
### Custom foreign_key ###
|
153
181
|
|
154
|
-
You can
|
182
|
+
You can explicitly specifiy a foreign_key for AaT to use should the key differ from the default:
|
155
183
|
|
156
184
|
```ruby
|
157
|
-
acts_as_tenant(:account, :foreign_key => 'accountID) # by default AaT expects account_id
|
185
|
+
acts_as_tenant(:account, :foreign_key => 'accountID') # by default AaT expects account_id
|
186
|
+
```
|
187
|
+
|
188
|
+
### Custom primary_key ###
|
189
|
+
|
190
|
+
You can also explicitly specifiy a primary_key for AaT to use should the key differ from the default:
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
acts_as_tenant(:account, :primary_key => 'primaryID') # by default AaT expects id
|
158
194
|
```
|
159
195
|
|
160
196
|
Configuration options
|
@@ -183,24 +219,42 @@ require 'acts_as_tenant/sidekiq'
|
|
183
219
|
Testing
|
184
220
|
---------------
|
185
221
|
|
186
|
-
If you set the `current_tenant` in your tests, make sure to clean up the tenant after each test by calling `ActsAsTenant.current_tenant = nil`.
|
222
|
+
If you set the `current_tenant` in your tests, make sure to clean up the tenant after each test by calling `ActsAsTenant.current_tenant = nil`. Integration tests are more difficult: manually setting the `current_tenant` value will not survive across multiple requests, even if they take place within the same test. This can result in undesired boilerplate to set the desired tenant. Moreover, the efficacy of the test can be compromised because the set `current_tenant` value will carry over into the request-response cycle.
|
187
223
|
|
188
|
-
|
224
|
+
To address this issue, ActsAsTenant provides for a `test_tenant` value that can be set to allow for setup and post-request expectation testing. It should be used in conjunction with middleware that clears out this value while an integration test is processing. A typical Rails and RSpec setup might look like:
|
189
225
|
|
190
226
|
```ruby
|
191
|
-
#
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
227
|
+
# test.rb
|
228
|
+
require_dependency 'acts_as_tenant/test_tenant_middleware'
|
229
|
+
|
230
|
+
Rails.application.configure do
|
231
|
+
config.middleware.use ActsAsTenant::TestTenantMiddleware
|
232
|
+
end
|
197
233
|
```
|
198
234
|
|
199
|
-
|
235
|
+
```ruby
|
236
|
+
# spec_helper.rb
|
237
|
+
config.before(:suite) do |example|
|
238
|
+
# Make the default tenant globally available to the tests
|
239
|
+
$default_account = Account.create!
|
240
|
+
end
|
200
241
|
|
201
|
-
|
202
|
-
|
203
|
-
|
242
|
+
config.before(:each) do |example|
|
243
|
+
if example.metadata[:type] == :request
|
244
|
+
# Set the `test_tenant` value for integration tests
|
245
|
+
ActsAsTenant.test_tenant = $default_account
|
246
|
+
else
|
247
|
+
# Otherwise just use current_tenant
|
248
|
+
ActsAsTenant.current_tenant = $default_account
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
config.after(:each) do |example|
|
253
|
+
# Clear any tenancy that might have been set
|
254
|
+
ActsAsTenant.current_tenant = nil
|
255
|
+
ActsAsTenant.test_tenant = nil
|
256
|
+
end
|
257
|
+
```
|
204
258
|
|
205
259
|
Bug reports & suggested improvements
|
206
260
|
------------------------------------
|
@@ -210,13 +264,20 @@ If you have found a bug or want to suggest an improvement, please use our issue
|
|
210
264
|
|
211
265
|
If you want to contribute, fork the project, code your improvements and make a pull request on [Github](http://github.com/ErwinM/acts_as_tenant/). When doing so, please don't forget to add tests. If your contribution is fixing a bug it would be perfect if you could also submit a failing test, illustrating the issue.
|
212
266
|
|
213
|
-
|
214
|
-
|
215
|
-
|
267
|
+
Contributing to this gem
|
268
|
+
------------------------
|
269
|
+
|
270
|
+
We use the Appraisal gem to run tests against supported versions of Rails to test for compatibility against them all. StandardRb also helps keep code formatted cleanly.
|
271
|
+
|
272
|
+
1. Fork the repo
|
273
|
+
2. Make changes
|
274
|
+
3. Run test suite with `bundle exec appraisal`
|
275
|
+
4. Run `bundle exec standardrb` to standardize code formatting
|
276
|
+
5. Submit a PR
|
216
277
|
|
217
278
|
Author & Credits
|
218
279
|
----------------
|
219
|
-
acts_as_tenant is written by Erwin Matthijssen.
|
280
|
+
acts_as_tenant is written by Erwin Matthijssen & Chris Oliver.
|
220
281
|
|
221
282
|
This gem was inspired by Ryan Sonnek's [Multitenant](https://github.com/wireframe/multitenant) gem and its use of default_scope.
|
222
283
|
|
data/Rakefile
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require "bundler/gem_tasks"
|
2
2
|
|
3
|
-
|
3
|
+
APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
|
4
|
+
|
5
|
+
require "rspec/core/rake_task"
|
4
6
|
RSpec::Core::RakeTask.new(:spec)
|
5
|
-
task :
|
7
|
+
task default: :spec
|
data/lib/acts_as_tenant.rb
CHANGED
@@ -1,27 +1,125 @@
|
|
1
1
|
require "request_store"
|
2
2
|
|
3
|
-
#$LOAD_PATH.unshift(File.dirname(__FILE__))
|
4
|
-
|
5
3
|
require "acts_as_tenant/version"
|
6
4
|
require "acts_as_tenant/errors"
|
7
|
-
require "acts_as_tenant/configuration"
|
8
|
-
require "acts_as_tenant/controller_extensions"
|
9
|
-
require "acts_as_tenant/model_extensions"
|
10
5
|
|
11
|
-
|
6
|
+
module ActsAsTenant
|
7
|
+
autoload :Configuration, "acts_as_tenant/configuration"
|
8
|
+
autoload :ControllerExtensions, "acts_as_tenant/controller_extensions"
|
9
|
+
autoload :ModelExtensions, "acts_as_tenant/model_extensions"
|
10
|
+
autoload :TenantHelper, "acts_as_tenant/tenant_helper"
|
11
|
+
|
12
|
+
@@configuration = nil
|
13
|
+
@@tenant_klass = nil
|
14
|
+
@@models_with_global_records = []
|
15
|
+
|
16
|
+
class << self
|
17
|
+
attr_accessor :test_tenant
|
18
|
+
attr_writer :default_tenant
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.configure
|
22
|
+
@@configuration = Configuration.new
|
23
|
+
yield configuration if block_given?
|
24
|
+
configuration
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.configuration
|
28
|
+
@@configuration || configure
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.set_tenant_klass(klass)
|
32
|
+
@@tenant_klass = klass
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.tenant_klass
|
36
|
+
@@tenant_klass
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.models_with_global_records
|
40
|
+
@@models_with_global_records
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.add_global_record_model model
|
44
|
+
@@models_with_global_records.push(model)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.fkey
|
48
|
+
"#{@@tenant_klass}_id"
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.pkey
|
52
|
+
ActsAsTenant.configuration.pkey
|
53
|
+
end
|
12
54
|
|
13
|
-
|
14
|
-
|
55
|
+
def self.polymorphic_type
|
56
|
+
"#{@@tenant_klass}_type"
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.current_tenant=(tenant)
|
60
|
+
RequestStore.store[:current_tenant] = tenant
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.current_tenant
|
64
|
+
RequestStore.store[:current_tenant] || test_tenant || default_tenant
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.unscoped=(unscoped)
|
68
|
+
RequestStore.store[:acts_as_tenant_unscoped] = unscoped
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.unscoped
|
72
|
+
RequestStore.store[:acts_as_tenant_unscoped]
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.unscoped?
|
76
|
+
!!unscoped
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.default_tenant
|
80
|
+
@default_tenant unless unscoped
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.with_tenant(tenant, &block)
|
84
|
+
if block.nil?
|
85
|
+
raise ArgumentError, "block required"
|
86
|
+
end
|
87
|
+
|
88
|
+
old_tenant = current_tenant
|
89
|
+
self.current_tenant = tenant
|
90
|
+
value = block.call
|
91
|
+
value
|
92
|
+
ensure
|
93
|
+
self.current_tenant = old_tenant
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.without_tenant(&block)
|
97
|
+
if block.nil?
|
98
|
+
raise ArgumentError, "block required"
|
99
|
+
end
|
100
|
+
|
101
|
+
old_tenant = current_tenant
|
102
|
+
old_unscoped = unscoped
|
103
|
+
|
104
|
+
self.current_tenant = nil
|
105
|
+
self.unscoped = true
|
106
|
+
value = block.call
|
107
|
+
value
|
108
|
+
ensure
|
109
|
+
self.current_tenant = old_tenant
|
110
|
+
self.unscoped = old_unscoped
|
111
|
+
end
|
15
112
|
end
|
16
113
|
|
17
|
-
|
18
|
-
|
114
|
+
ActiveSupport.on_load(:active_record) do |base|
|
115
|
+
base.include ActsAsTenant::ModelExtensions
|
19
116
|
end
|
20
117
|
|
21
|
-
|
22
|
-
|
118
|
+
ActiveSupport.on_load(:action_controller) do |base|
|
119
|
+
base.extend ActsAsTenant::ControllerExtensions
|
120
|
+
base.include ActsAsTenant::TenantHelper
|
23
121
|
end
|
24
122
|
|
25
|
-
|
123
|
+
ActiveSupport.on_load(:action_view) do |base|
|
124
|
+
base.include ActsAsTenant::TenantHelper
|
26
125
|
end
|
27
|
-
|
@@ -1,26 +1,13 @@
|
|
1
1
|
module ActsAsTenant
|
2
|
-
@@configuration = nil
|
3
|
-
|
4
|
-
def self.configure
|
5
|
-
@@configuration = Configuration.new
|
6
|
-
|
7
|
-
if block_given?
|
8
|
-
yield configuration
|
9
|
-
end
|
10
|
-
|
11
|
-
configuration
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.configuration
|
15
|
-
@@configuration || configure
|
16
|
-
end
|
17
|
-
|
18
2
|
class Configuration
|
19
|
-
attr_writer :require_tenant
|
20
|
-
|
3
|
+
attr_writer :require_tenant, :pkey
|
4
|
+
|
21
5
|
def require_tenant
|
22
6
|
@require_tenant ||= false
|
23
7
|
end
|
24
|
-
|
8
|
+
|
9
|
+
def pkey
|
10
|
+
@pkey ||= :id
|
11
|
+
end
|
25
12
|
end
|
26
13
|
end
|
@@ -1,85 +1,36 @@
|
|
1
1
|
module ActsAsTenant
|
2
2
|
module ControllerExtensions
|
3
|
+
autoload :Filter, "acts_as_tenant/controller_extensions/filter"
|
4
|
+
autoload :Subdomain, "acts_as_tenant/controller_extensions/subdomain"
|
5
|
+
autoload :SubdomainOrDomain, "acts_as_tenant/controller_extensions/subdomain_or_domain"
|
3
6
|
|
4
7
|
# this method allows setting the current_tenant by reading the subdomain and looking
|
5
8
|
# it up in the tenant-model passed to the method. The method will look for the subdomain
|
6
9
|
# in a column referenced by the second argument.
|
7
|
-
def set_current_tenant_by_subdomain(tenant = :account, column = :subdomain )
|
8
|
-
|
9
|
-
cattr_accessor :tenant_class, :tenant_column
|
10
|
-
end
|
10
|
+
def set_current_tenant_by_subdomain(tenant = :account, column = :subdomain, subdomain_lookup: :last)
|
11
|
+
include Subdomain
|
11
12
|
|
12
13
|
self.tenant_class = tenant.to_s.camelcase.constantize
|
13
14
|
self.tenant_column = column.to_sym
|
14
|
-
|
15
|
-
self.class_eval do
|
16
|
-
|
17
|
-
before_action :find_tenant_by_subdomain
|
18
|
-
helper_method :current_tenant if respond_to?(:helper_method)
|
19
|
-
|
20
|
-
|
21
|
-
private
|
22
|
-
def find_tenant_by_subdomain
|
23
|
-
if request.subdomains.last
|
24
|
-
ActsAsTenant.current_tenant = tenant_class.where(tenant_column => request.subdomains.last.downcase).first
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def current_tenant
|
29
|
-
ActsAsTenant.current_tenant
|
30
|
-
end
|
31
|
-
end
|
15
|
+
self.subdomain_lookup = subdomain_lookup
|
32
16
|
end
|
33
17
|
|
34
18
|
# 01/27/2014 Christian Yerena / @preth00nker
|
35
19
|
# this method adds the possibility of use the domain as a possible second argument to find
|
36
20
|
# the current_tenant.
|
37
|
-
def set_current_tenant_by_subdomain_or_domain(tenant = :account, primary_column = :subdomain, second_column = :domain )
|
38
|
-
|
39
|
-
cattr_accessor :tenant_class, :tenant_primary_column, :tenant_second_column
|
40
|
-
end
|
21
|
+
def set_current_tenant_by_subdomain_or_domain(tenant = :account, primary_column = :subdomain, second_column = :domain, subdomain_lookup: :last)
|
22
|
+
include SubdomainOrDomain
|
41
23
|
|
42
24
|
self.tenant_class = tenant.to_s.camelcase.constantize
|
43
25
|
self.tenant_primary_column = primary_column.to_sym
|
44
26
|
self.tenant_second_column = second_column.to_sym
|
45
|
-
|
46
|
-
self.class_eval do
|
47
|
-
|
48
|
-
before_action :find_tenant_by_subdomain_or_domain
|
49
|
-
helper_method :current_tenant if respond_to?(:helper_method)
|
50
|
-
|
51
|
-
|
52
|
-
private
|
53
|
-
def find_tenant_by_subdomain_or_domain
|
54
|
-
if request.subdomains.last
|
55
|
-
ActsAsTenant.current_tenant = tenant_class.where(tenant_primary_column => request.subdomains.last.downcase).first
|
56
|
-
else
|
57
|
-
ActsAsTenant.current_tenant = tenant_class.where(tenant_second_column => request.domain.downcase).first
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def current_tenant
|
62
|
-
ActsAsTenant.current_tenant
|
63
|
-
end
|
64
|
-
end
|
27
|
+
self.subdomain_lookup = subdomain_lookup
|
65
28
|
end
|
66
29
|
|
67
|
-
|
68
30
|
# This method sets up a method that allows manual setting of the current_tenant. This method should
|
69
31
|
# be used in a before_action. In addition, a helper is setup that returns the current_tenant
|
70
32
|
def set_current_tenant_through_filter
|
71
|
-
|
72
|
-
helper_method :current_tenant if respond_to?(:helper_method)
|
73
|
-
|
74
|
-
private
|
75
|
-
def set_current_tenant(current_tenant_object)
|
76
|
-
ActsAsTenant.current_tenant = current_tenant_object
|
77
|
-
end
|
78
|
-
|
79
|
-
def current_tenant
|
80
|
-
ActsAsTenant.current_tenant
|
81
|
-
end
|
82
|
-
end
|
33
|
+
include Filter
|
83
34
|
end
|
84
35
|
end
|
85
36
|
end
|