acts_as_tenant 0.4.2 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +124 -25
- data/Rakefile +5 -3
- data/lib/acts_as_tenant/configuration.rb +6 -19
- 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/controller_extensions.rb +10 -59
- data/lib/acts_as_tenant/errors.rb +3 -4
- data/lib/acts_as_tenant/model_extensions.rb +59 -136
- data/lib/acts_as_tenant/sidekiq.rb +16 -8
- 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/lib/acts_as_tenant.rb +112 -14
- 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/global_project_with_conditions.rb +6 -0
- data/spec/dummy/app/models/global_project_with_if.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/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/config.ru +5 -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 +413 -0
- data/spec/spec_helper.rb +9 -13
- metadata +205 -41
- data/.gitignore +0 -7
- data/.travis.yml +0 -4
- data/CHANGELOG.md +0 -108
- 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 -116
- data/spec/acts_as_tenant/model_extensions_spec.rb +0 -420
- 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: b9dbb40015b39583a44c37496f0687641e1a66f9b70357260b1fcabe7f3c542d
|
4
|
+
data.tar.gz: 88d1ce36220fd3c8e8264b95d76afb7f883cc77da0ac9f12538cde682fa9dacf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d76fbf4cc3381afdfa2c02627ad6de56ff9e4cdaa636da4103e11e38ee48a6f6ecf3f432f296bfd3b8ae5cfc690d8fc52cbc7e025953e39cf3b3dab4439d3f1
|
7
|
+
data.tar.gz: ba09cb46b06f2399de2ac2e4d6efa3369d22e287a6741bfd0fcfc483836b64ac96851dd671dd4a97bace409c7aa72f6e7fc03394250f853c55a54159e720118a
|
data/README.md
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
Acts As Tenant
|
2
|
-
==============
|
1
|
+
# Acts As Tenant
|
3
2
|
|
4
|
-
[![Build Status](https://
|
3
|
+
[![Build Status](https://github.com/ErwinM/acts_as_tenant/workflows/Tests/badge.svg)](https://github.com/ErwinM/acts_as_tenant/actions) [![Gem Version](https://badge.fury.io/rb/acts_as_tenant.svg)](https://badge.fury.io/rb/acts_as_tenant)
|
5
4
|
|
6
|
-
|
5
|
+
Row-level multitenancy for Ruby on Rails apps.
|
7
6
|
|
8
7
|
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
8
|
|
@@ -16,9 +15,27 @@ In addition, acts_as_tenant:
|
|
16
15
|
* adds a method to validate uniqueness to a tenant, `validates_uniqueness_to_tenant`
|
17
16
|
* sets up a helper method containing the current tenant
|
18
17
|
|
18
|
+
**Note**: acts_as_tenant was introduced in this [blog post](https://github.com/ErwinM/acts_as_tenant/blob/master/docs/blog_post.md).
|
19
|
+
|
20
|
+
**Row-level vs schema multitenancy**
|
21
|
+
|
22
|
+
What's the difference?
|
23
|
+
|
24
|
+
Row-level multitenancy each model must have a tenant ID column on it. This makes it easy to filter records for each tenant using your standard database columns and indexes. ActsAsTenant uses row-level multitenancy.
|
25
|
+
|
26
|
+
Schema multitenancy uses database schemas to handle multitenancy. For this approach, your database has multiple schemas and each schema contains your database tables. Schemas require migrations to be run against each tenant and generally makes it harder to scale as you add more tenants. The Apartment gem uses schema multitenancy.
|
27
|
+
|
28
|
+
#### 🎬 Walkthrough
|
29
|
+
|
30
|
+
Want to see how it works? Check out [the ActsAsTenant walkthrough video](https://www.youtube.com/watch?v=BIyxM9f8Jus):
|
31
|
+
|
32
|
+
<a href="https://www.youtube.com/watch?v=BIyxM9f8Jus">
|
33
|
+
<img src="https://i.imgur.com/DLRPzhv.png" width="300" height="auto" alt="ActsAsTenant Walkthrough Video">
|
34
|
+
</a>
|
35
|
+
|
19
36
|
Installation
|
20
37
|
------------
|
21
|
-
acts_as_tenant will only work on Rails
|
38
|
+
acts_as_tenant will only work on Rails 5.2 and up. This is due to changes made to the handling of `default_scope`, an essential pillar of the gem.
|
22
39
|
|
23
40
|
To use it, add it to your Gemfile:
|
24
41
|
|
@@ -41,7 +58,8 @@ There are three ways to set the current tenant:
|
|
41
58
|
2. by setting the current tenant in the controller, and
|
42
59
|
3. by setting the current tenant for a block.
|
43
60
|
|
44
|
-
###
|
61
|
+
### Looking Up Tenants
|
62
|
+
#### By Subdomain to lookup the current tenant
|
45
63
|
|
46
64
|
```ruby
|
47
65
|
class ApplicationController < ActionController::Base
|
@@ -49,11 +67,23 @@ class ApplicationController < ActionController::Base
|
|
49
67
|
end
|
50
68
|
```
|
51
69
|
|
52
|
-
This tells acts_as_tenant to use the
|
70
|
+
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.
|
71
|
+
|
72
|
+
By default, the *last* subdomain will be used for lookup. Pass in `subdomain_lookup: :first` to use the first subdomain instead.
|
73
|
+
|
74
|
+
#### By Domain to lookup the current tenant
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
class ApplicationController < ActionController::Base
|
78
|
+
set_current_tenant_by_subdomain_or_domain(:account, :subdomain, :domain)
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
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
83
|
|
54
|
-
|
84
|
+
By default, the *last* subdomain will be used for lookup. Pass in `subdomain_lookup: :first` to use the first subdomain instead.
|
55
85
|
|
56
|
-
|
86
|
+
#### Manually using before_action
|
57
87
|
|
58
88
|
```ruby
|
59
89
|
class ApplicationController < ActionController::Base
|
@@ -69,6 +99,21 @@ end
|
|
69
99
|
|
70
100
|
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
101
|
|
102
|
+
If you are setting the tenant in a specific controller (except `application_controller`), it should to be included **AT THE TOP** of the file.
|
103
|
+
|
104
|
+
```
|
105
|
+
class MembersController < ActionController::Base
|
106
|
+
set_current_tenant_through_filter
|
107
|
+
before_action :set_tenant
|
108
|
+
before_action :set_member, only: [:show, :edit, :update, :destroy]
|
109
|
+
|
110
|
+
def set_tenant
|
111
|
+
set_current_tenant(current_user.account)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
This allows the tenant to be set before any other code runs so everything is within the current tenant.
|
72
117
|
|
73
118
|
### Setting the current tenant for a block ###
|
74
119
|
|
@@ -94,7 +139,7 @@ This is useful in shared routes such as admin panels or internal dashboards when
|
|
94
139
|
|
95
140
|
### Require tenant to be set always ###
|
96
141
|
|
97
|
-
If you want to require the tenant to be set at all times, you can configure acts_as_tenant to raise an error when a query is made without a tenant available. See below under
|
142
|
+
If you want to require the tenant to be set at all times, you can configure acts_as_tenant to raise an error when a query is made without a tenant available. See below under configuration options.
|
98
143
|
|
99
144
|
Scoping your models
|
100
145
|
-------------------
|
@@ -151,10 +196,18 @@ All options available to Rails' own `validates_uniqueness_of` are also available
|
|
151
196
|
|
152
197
|
### Custom foreign_key ###
|
153
198
|
|
154
|
-
You can
|
199
|
+
You can explicitly specifiy a foreign_key for AaT to use should the key differ from the default:
|
155
200
|
|
156
201
|
```ruby
|
157
|
-
acts_as_tenant(:account, :foreign_key => 'accountID) # by default AaT expects account_id
|
202
|
+
acts_as_tenant(:account, :foreign_key => 'accountID') # by default AaT expects account_id
|
203
|
+
```
|
204
|
+
|
205
|
+
### Custom primary_key ###
|
206
|
+
|
207
|
+
You can also explicitly specifiy a primary_key for AaT to use should the key differ from the default:
|
208
|
+
|
209
|
+
```ruby
|
210
|
+
acts_as_tenant(:account, :primary_key => 'primaryID') # by default AaT expects id
|
158
211
|
```
|
159
212
|
|
160
213
|
Configuration options
|
@@ -170,6 +223,23 @@ end
|
|
170
223
|
|
171
224
|
* `config.require_tenant` when set to true will raise an ActsAsTenant::NoTenant error whenever a query is made without a tenant set.
|
172
225
|
|
226
|
+
belongs_to options
|
227
|
+
---------------------
|
228
|
+
`acts_as_tenant :account` includes the belongs_to relationship.
|
229
|
+
So when using acts_as_tenant on a model, do not add `belongs_to :account` alongside `acts_as_tenant :account`:
|
230
|
+
|
231
|
+
```
|
232
|
+
class User < ActiveRecord::Base
|
233
|
+
acts_as_tenant(:account) # YES
|
234
|
+
belongs_to :account # REDUNDANT
|
235
|
+
end
|
236
|
+
```
|
237
|
+
|
238
|
+
You can add the following `belongs_to` options to `acts_as_tenant`:
|
239
|
+
`:foreign_key, :class_name, :inverse_of, :optional, :primary_key, :counter_cache`
|
240
|
+
|
241
|
+
Example: `acts_as_tenant(:account, counter_cache: true)`
|
242
|
+
|
173
243
|
Sidekiq support
|
174
244
|
---------------
|
175
245
|
|
@@ -183,24 +253,42 @@ require 'acts_as_tenant/sidekiq'
|
|
183
253
|
Testing
|
184
254
|
---------------
|
185
255
|
|
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`.
|
256
|
+
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
257
|
|
188
|
-
|
258
|
+
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
259
|
|
190
260
|
```ruby
|
191
|
-
#
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
261
|
+
# test.rb
|
262
|
+
require_dependency 'acts_as_tenant/test_tenant_middleware'
|
263
|
+
|
264
|
+
Rails.application.configure do
|
265
|
+
config.middleware.use ActsAsTenant::TestTenantMiddleware
|
266
|
+
end
|
197
267
|
```
|
198
268
|
|
199
|
-
|
269
|
+
```ruby
|
270
|
+
# spec_helper.rb
|
271
|
+
config.before(:suite) do |example|
|
272
|
+
# Make the default tenant globally available to the tests
|
273
|
+
$default_account = Account.create!
|
274
|
+
end
|
200
275
|
|
201
|
-
|
202
|
-
|
203
|
-
|
276
|
+
config.before(:each) do |example|
|
277
|
+
if example.metadata[:type] == :request
|
278
|
+
# Set the `test_tenant` value for integration tests
|
279
|
+
ActsAsTenant.test_tenant = $default_account
|
280
|
+
else
|
281
|
+
# Otherwise just use current_tenant
|
282
|
+
ActsAsTenant.current_tenant = $default_account
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
config.after(:each) do |example|
|
287
|
+
# Clear any tenancy that might have been set
|
288
|
+
ActsAsTenant.current_tenant = nil
|
289
|
+
ActsAsTenant.test_tenant = nil
|
290
|
+
end
|
291
|
+
```
|
204
292
|
|
205
293
|
Bug reports & suggested improvements
|
206
294
|
------------------------------------
|
@@ -210,9 +298,20 @@ If you have found a bug or want to suggest an improvement, please use our issue
|
|
210
298
|
|
211
299
|
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
300
|
|
301
|
+
Contributing to this gem
|
302
|
+
------------------------
|
303
|
+
|
304
|
+
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.
|
305
|
+
|
306
|
+
1. Fork the repo
|
307
|
+
2. Make changes
|
308
|
+
3. Run test suite with `bundle exec appraisal`
|
309
|
+
4. Run `bundle exec standardrb` to standardize code formatting
|
310
|
+
5. Submit a PR
|
311
|
+
|
213
312
|
Author & Credits
|
214
313
|
----------------
|
215
|
-
acts_as_tenant is written by Erwin Matthijssen.
|
314
|
+
acts_as_tenant is written by Erwin Matthijssen & Chris Oliver.
|
216
315
|
|
217
316
|
This gem was inspired by Ryan Sonnek's [Multitenant](https://github.com/wireframe/multitenant) gem and its use of default_scope.
|
218
317
|
|
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
|
@@ -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
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ActsAsTenant
|
2
|
+
module ControllerExtensions
|
3
|
+
module Subdomain
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
cattr_accessor :tenant_class, :tenant_column, :subdomain_lookup
|
8
|
+
before_action :find_tenant_by_subdomain
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def find_tenant_by_subdomain
|
14
|
+
if (subdomain = request.subdomains.send(subdomain_lookup))
|
15
|
+
ActsAsTenant.current_tenant = tenant_class.where(tenant_column => subdomain.downcase).first
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ActsAsTenant
|
2
|
+
module ControllerExtensions
|
3
|
+
module SubdomainOrDomain
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
cattr_accessor :tenant_class, :tenant_primary_column, :tenant_second_column, :subdomain_lookup
|
8
|
+
before_action :find_tenant_by_subdomain_or_domain
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def find_tenant_by_subdomain_or_domain
|
14
|
+
subdomain = request.subdomains.send(subdomain_lookup)
|
15
|
+
query = subdomain.present? ? {tenant_primary_column => subdomain.downcase} : {tenant_second_column => request.domain.downcase}
|
16
|
+
ActsAsTenant.current_tenant = tenant_class.where(query).first
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
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
|
@@ -5,15 +5,14 @@ module ActsAsTenant
|
|
5
5
|
module Errors
|
6
6
|
class ModelNotScopedByTenant < ActsAsTenant::Error
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
class NoTenantSet < ActsAsTenant::Error
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
class ModelNotScopedByTenant < ActsAsTenant::Error
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
class TenantIsImmutable < ActsAsTenant::Error
|
16
16
|
end
|
17
|
-
|
18
17
|
end
|
19
18
|
end
|