acts_as_tenant 0.4.4 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +158 -27
- 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 +2 -6
- data/lib/acts_as_tenant/model_extensions.rb +63 -155
- 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/lib/acts_as_tenant.rb +130 -14
- metadata +46 -48
- 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/configuration_spec.rb +0 -28
- data/spec/acts_as_tenant/model_extensions_spec.rb +0 -476
- data/spec/acts_as_tenant/sidekiq_spec.rb +0 -63
- data/spec/acts_as_tenant/tenant_by_filter_spec.rb +0 -33
- 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
- data/spec/spec_helper.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 82765cfa1d00a63aa012f3ab5de9ddd60ae2c8041df405e08ae70ef20382d7ee
|
4
|
+
data.tar.gz: ba1920a299f84a4e6424304539c05ca69515e3b17e73ffb1b6635fbce79ae77c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62854b28ba5293d5437f5614032e992d914bc0741be3e8b925231116802d85b19d9631fc2e0ff2a7775e3259a998e4239f0b38c7ddf97c6817a0db96fbf488c5
|
7
|
+
data.tar.gz: 2e6c875895dd15882ffc4454f0c0bfae4fc3e77df17deae58710835e92bf32761247ab3b60cdfe9a83b81f72e2ea698c59f0155c046dfe2af5c62450a4bd65ca
|
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
|
+
```ruby
|
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
|
|
@@ -151,10 +196,40 @@ 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:
|
200
|
+
|
201
|
+
```ruby
|
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:
|
155
208
|
|
156
209
|
```ruby
|
157
|
-
acts_as_tenant(:account, :
|
210
|
+
acts_as_tenant(:account, :primary_key => 'primaryID') # by default AaT expects id
|
211
|
+
```
|
212
|
+
|
213
|
+
|
214
|
+
### Has and belongs to many ###
|
215
|
+
|
216
|
+
You can scope a model that is part of a HABTM relationship by using the `through` option.
|
217
|
+
|
218
|
+
```ruby
|
219
|
+
class Organisation < ActiveRecord::Base
|
220
|
+
has_many :organisations_users
|
221
|
+
has_many :users, through: :organisations_users
|
222
|
+
end
|
223
|
+
|
224
|
+
class User < ActiveRecord::Base
|
225
|
+
has_many :organisations_users
|
226
|
+
acts_as_tenant :organisation, through: :organisations_users
|
227
|
+
end
|
228
|
+
|
229
|
+
class OrganisationsUser < ActiveRecord::Base
|
230
|
+
belongs_to :user
|
231
|
+
acts_as_tenant :organisation
|
232
|
+
end
|
158
233
|
```
|
159
234
|
|
160
235
|
Configuration options
|
@@ -170,6 +245,37 @@ end
|
|
170
245
|
|
171
246
|
* `config.require_tenant` when set to true will raise an ActsAsTenant::NoTenant error whenever a query is made without a tenant set.
|
172
247
|
|
248
|
+
`config.require_tenant` can also be assigned a lambda that is evaluated at run time. For example:
|
249
|
+
|
250
|
+
```ruby
|
251
|
+
ActsAsTenant.configure do |config|
|
252
|
+
config.require_tenant = lambda do
|
253
|
+
if $request_env.present?
|
254
|
+
return false if $request_env["REQUEST_PATH"].start_with?("/admin/")
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
```
|
259
|
+
|
260
|
+
`ActsAsTenant.should_require_tenant?` is used to determine if a tenant is required in the current context, either by evaluating the lambda provided, or by returning the boolean value assigned to `config.require_tenant`.
|
261
|
+
|
262
|
+
belongs_to options
|
263
|
+
---------------------
|
264
|
+
`acts_as_tenant :account` includes the belongs_to relationship.
|
265
|
+
So when using acts_as_tenant on a model, do not add `belongs_to :account` alongside `acts_as_tenant :account`:
|
266
|
+
|
267
|
+
```ruby
|
268
|
+
class User < ActiveRecord::Base
|
269
|
+
acts_as_tenant(:account) # YES
|
270
|
+
belongs_to :account # REDUNDANT
|
271
|
+
end
|
272
|
+
```
|
273
|
+
|
274
|
+
You can add the following `belongs_to` options to `acts_as_tenant`:
|
275
|
+
`:foreign_key, :class_name, :inverse_of, :optional, :primary_key, :counter_cache`
|
276
|
+
|
277
|
+
Example: `acts_as_tenant(:account, counter_cache: true)`
|
278
|
+
|
173
279
|
Sidekiq support
|
174
280
|
---------------
|
175
281
|
|
@@ -183,24 +289,42 @@ require 'acts_as_tenant/sidekiq'
|
|
183
289
|
Testing
|
184
290
|
---------------
|
185
291
|
|
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`.
|
292
|
+
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
293
|
|
188
|
-
|
294
|
+
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
295
|
|
190
296
|
```ruby
|
191
|
-
#
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
297
|
+
# test.rb
|
298
|
+
require_dependency 'acts_as_tenant/test_tenant_middleware'
|
299
|
+
|
300
|
+
Rails.application.configure do
|
301
|
+
config.middleware.use ActsAsTenant::TestTenantMiddleware
|
302
|
+
end
|
197
303
|
```
|
198
304
|
|
199
|
-
|
305
|
+
```ruby
|
306
|
+
# spec_helper.rb
|
307
|
+
config.before(:suite) do |example|
|
308
|
+
# Make the default tenant globally available to the tests
|
309
|
+
$default_account = Account.create!
|
310
|
+
end
|
311
|
+
|
312
|
+
config.before(:each) do |example|
|
313
|
+
if example.metadata[:type] == :request
|
314
|
+
# Set the `test_tenant` value for integration tests
|
315
|
+
ActsAsTenant.test_tenant = $default_account
|
316
|
+
else
|
317
|
+
# Otherwise just use current_tenant
|
318
|
+
ActsAsTenant.current_tenant = $default_account
|
319
|
+
end
|
320
|
+
end
|
200
321
|
|
201
|
-
|
202
|
-
|
203
|
-
|
322
|
+
config.after(:each) do |example|
|
323
|
+
# Clear any tenancy that might have been set
|
324
|
+
ActsAsTenant.current_tenant = nil
|
325
|
+
ActsAsTenant.test_tenant = nil
|
326
|
+
end
|
327
|
+
```
|
204
328
|
|
205
329
|
Bug reports & suggested improvements
|
206
330
|
------------------------------------
|
@@ -210,13 +334,20 @@ If you have found a bug or want to suggest an improvement, please use our issue
|
|
210
334
|
|
211
335
|
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
336
|
|
213
|
-
|
214
|
-
|
215
|
-
|
337
|
+
Contributing to this gem
|
338
|
+
------------------------
|
339
|
+
|
340
|
+
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.
|
341
|
+
|
342
|
+
1. Fork the repo
|
343
|
+
2. Make changes
|
344
|
+
3. Run test suite with `bundle exec appraisal`
|
345
|
+
4. Run `bundle exec standardrb` to standardize code formatting
|
346
|
+
5. Submit a PR
|
216
347
|
|
217
348
|
Author & Credits
|
218
349
|
----------------
|
219
|
-
acts_as_tenant is written by Erwin Matthijssen.
|
350
|
+
acts_as_tenant is written by Erwin Matthijssen & Chris Oliver.
|
220
351
|
|
221
352
|
This gem was inspired by Ryan Sonnek's [Multitenant](https://github.com/wireframe/multitenant) gem and its use of default_scope.
|
222
353
|
|
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,11 @@ 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
|
-
|
12
|
-
class ModelNotScopedByTenant < ActsAsTenant::Error
|
13
|
-
end
|
14
|
-
|
11
|
+
|
15
12
|
class TenantIsImmutable < ActsAsTenant::Error
|
16
13
|
end
|
17
|
-
|
18
14
|
end
|
19
15
|
end
|