acts_as_tenant 0.5.1 → 0.6.1
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 +4 -4
- data/README.md +51 -5
- data/lib/acts_as_tenant/errors.rb +0 -3
- data/lib/acts_as_tenant/model_extensions.rb +20 -9
- data/lib/acts_as_tenant/sidekiq.rb +12 -2
- data/lib/acts_as_tenant/version.rb +1 -1
- data/lib/acts_as_tenant.rb +35 -1
- metadata +4 -170
- data/spec/acts_as_tenant/configuration_spec.rb +0 -17
- data/spec/acts_as_tenant/sidekiq_spec.rb +0 -58
- data/spec/controllers/filter_spec.rb +0 -28
- data/spec/controllers/subdomain_or_domain_spec.rb +0 -55
- data/spec/controllers/subdomain_spec.rb +0 -49
- data/spec/dummy/.ruby-version +0 -1
- data/spec/dummy/Rakefile +0 -6
- data/spec/dummy/app/assets/config/manifest.js +0 -2
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/stylesheets/application.css +0 -15
- data/spec/dummy/app/channels/application_cable/channel.rb +0 -4
- data/spec/dummy/app/channels/application_cable/connection.rb +0 -4
- data/spec/dummy/app/controllers/application_controller.rb +0 -2
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +0 -2
- data/spec/dummy/app/javascript/packs/application.js +0 -15
- data/spec/dummy/app/jobs/application_job.rb +0 -7
- data/spec/dummy/app/mailers/application_mailer.rb +0 -4
- data/spec/dummy/app/mailers/user_mailer.rb +0 -5
- data/spec/dummy/app/models/account.rb +0 -4
- data/spec/dummy/app/models/aliased_task.rb +0 -4
- data/spec/dummy/app/models/article.rb +0 -3
- data/spec/dummy/app/models/comment.rb +0 -5
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/custom_counter_cache_task.rb +0 -4
- data/spec/dummy/app/models/custom_foreign_key_task.rb +0 -4
- data/spec/dummy/app/models/custom_primary_key_task.rb +0 -4
- data/spec/dummy/app/models/global_project.rb +0 -6
- data/spec/dummy/app/models/global_project_with_conditions.rb +0 -6
- data/spec/dummy/app/models/global_project_with_if.rb +0 -6
- data/spec/dummy/app/models/manager.rb +0 -4
- data/spec/dummy/app/models/polymorphic_tenant_comment.rb +0 -5
- data/spec/dummy/app/models/project.rb +0 -8
- data/spec/dummy/app/models/task.rb +0 -7
- data/spec/dummy/app/models/unique_task.rb +0 -5
- data/spec/dummy/app/models/unscoped_model.rb +0 -3
- data/spec/dummy/app/views/layouts/application.html.erb +0 -14
- data/spec/dummy/app/views/layouts/mailer.html.erb +0 -13
- data/spec/dummy/app/views/layouts/mailer.text.erb +0 -1
- data/spec/dummy/bin/rails +0 -4
- data/spec/dummy/bin/rake +0 -4
- data/spec/dummy/bin/setup +0 -33
- data/spec/dummy/config/application.rb +0 -19
- data/spec/dummy/config/boot.rb +0 -5
- data/spec/dummy/config/cable.yml +0 -10
- data/spec/dummy/config/database.yml +0 -19
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -62
- data/spec/dummy/config/environments/production.rb +0 -112
- data/spec/dummy/config/environments/test.rb +0 -49
- data/spec/dummy/config/initializers/application_controller_renderer.rb +0 -8
- data/spec/dummy/config/initializers/assets.rb +0 -12
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummy/config/initializers/content_security_policy.rb +0 -28
- data/spec/dummy/config/initializers/cookies_serializer.rb +0 -5
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -4
- data/spec/dummy/config/initializers/inflections.rb +0 -16
- data/spec/dummy/config/initializers/mime_types.rb +0 -4
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/spec/dummy/config/locales/en.yml +0 -40
- data/spec/dummy/config/puma.rb +0 -38
- data/spec/dummy/config/routes.rb +0 -4
- data/spec/dummy/config/spring.rb +0 -6
- data/spec/dummy/config/storage.yml +0 -34
- data/spec/dummy/config.ru +0 -5
- data/spec/dummy/db/schema.rb +0 -84
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +0 -67
- data/spec/dummy/public/422.html +0 -67
- data/spec/dummy/public/500.html +0 -66
- 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 +0 -1
- data/spec/fixtures/accounts.yml +0 -10
- data/spec/fixtures/custom_primary_key_tasks.yml +0 -2
- data/spec/fixtures/global_projects.yml +0 -13
- data/spec/fixtures/projects.yml +0 -10
- data/spec/helpers/tenant_helper_spec.rb +0 -16
- data/spec/middlewares/test_tenant_middleware_spec.rb +0 -86
- data/spec/models/model_extensions_spec.rb +0 -413
- data/spec/spec_helper.rb +0 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 157bb94b2c59bdc0699a43f247141e44f4f8b9f41979186d678e996adfdbda2e
|
|
4
|
+
data.tar.gz: c4f559b0b12e8e92fc5025f9c926f437f01742cca85c91f4e3d306373a0e3492
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f843cea7abb50c0745b51e0850b93176c4a0713dcc875d62c733b4ff1df3b5cd7d9d2bf0b46de892af7009dfe106a3932d6698ed0132a2411466f43ecf243123
|
|
7
|
+
data.tar.gz: 1efe052c243a8fc2a7d857d559945f99646f237cb16c22dd6219ea4f94697f2ecd299384ca86bb57758cd37e7773186f2f75becb66998c5c00218ffa0a42f3fd
|
data/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Row-level multitenancy each model must have a tenant ID column on it. This make
|
|
|
25
25
|
|
|
26
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
27
|
|
|
28
|
-
#### 🎬 Walkthrough
|
|
28
|
+
#### 🎬 Walkthrough
|
|
29
29
|
|
|
30
30
|
Want to see how it works? Check out [the ActsAsTenant walkthrough video](https://www.youtube.com/watch?v=BIyxM9f8Jus):
|
|
31
31
|
|
|
@@ -101,7 +101,7 @@ Setting the `current_tenant` yourself, requires you to declare `set_current_tena
|
|
|
101
101
|
|
|
102
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
103
|
|
|
104
|
-
```
|
|
104
|
+
```ruby
|
|
105
105
|
class MembersController < ActionController::Base
|
|
106
106
|
set_current_tenant_through_filter
|
|
107
107
|
before_action :set_tenant
|
|
@@ -137,6 +137,16 @@ end
|
|
|
137
137
|
```
|
|
138
138
|
This is useful in shared routes such as admin panels or internal dashboards when `require_tenant` option is enabled throughout the app.
|
|
139
139
|
|
|
140
|
+
### Allowing tenant updating for a block ###
|
|
141
|
+
|
|
142
|
+
```ruby
|
|
143
|
+
ActsAsTenant.with_mutable_tenant do
|
|
144
|
+
# Tenant updating is enabled for all code in this block
|
|
145
|
+
end
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
This will allow you to change the tenant of a model. This feature is useful for admin screens, where it is ok to allow certain users to change the tenant on existing models in specific cases.
|
|
149
|
+
|
|
140
150
|
### Require tenant to be set always ###
|
|
141
151
|
|
|
142
152
|
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.
|
|
@@ -210,6 +220,28 @@ You can also explicitly specifiy a primary_key for AaT to use should the key dif
|
|
|
210
220
|
acts_as_tenant(:account, :primary_key => 'primaryID') # by default AaT expects id
|
|
211
221
|
```
|
|
212
222
|
|
|
223
|
+
|
|
224
|
+
### Has and belongs to many ###
|
|
225
|
+
|
|
226
|
+
You can scope a model that is part of a HABTM relationship by using the `through` option.
|
|
227
|
+
|
|
228
|
+
```ruby
|
|
229
|
+
class Organisation < ActiveRecord::Base
|
|
230
|
+
has_many :organisations_users
|
|
231
|
+
has_many :users, through: :organisations_users
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
class User < ActiveRecord::Base
|
|
235
|
+
has_many :organisations_users
|
|
236
|
+
acts_as_tenant :organisation, through: :organisations_users
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
class OrganisationsUser < ActiveRecord::Base
|
|
240
|
+
belongs_to :user
|
|
241
|
+
acts_as_tenant :organisation
|
|
242
|
+
end
|
|
243
|
+
```
|
|
244
|
+
|
|
213
245
|
Configuration options
|
|
214
246
|
---------------------
|
|
215
247
|
An initializer can be created to control (currently one) option in ActsAsTenant. Defaults
|
|
@@ -223,12 +255,26 @@ end
|
|
|
223
255
|
|
|
224
256
|
* `config.require_tenant` when set to true will raise an ActsAsTenant::NoTenant error whenever a query is made without a tenant set.
|
|
225
257
|
|
|
258
|
+
`config.require_tenant` can also be assigned a lambda that is evaluated at run time. For example:
|
|
259
|
+
|
|
260
|
+
```ruby
|
|
261
|
+
ActsAsTenant.configure do |config|
|
|
262
|
+
config.require_tenant = lambda do
|
|
263
|
+
if $request_env.present?
|
|
264
|
+
return false if $request_env["REQUEST_PATH"].start_with?("/admin/")
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
`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`.
|
|
271
|
+
|
|
226
272
|
belongs_to options
|
|
227
273
|
---------------------
|
|
228
|
-
`acts_as_tenant :account` includes the belongs_to relationship.
|
|
274
|
+
`acts_as_tenant :account` includes the belongs_to relationship.
|
|
229
275
|
So when using acts_as_tenant on a model, do not add `belongs_to :account` alongside `acts_as_tenant :account`:
|
|
230
276
|
|
|
231
|
-
```
|
|
277
|
+
```ruby
|
|
232
278
|
class User < ActiveRecord::Base
|
|
233
279
|
acts_as_tenant(:account) # YES
|
|
234
280
|
belongs_to :account # REDUNDANT
|
|
@@ -236,7 +282,7 @@ end
|
|
|
236
282
|
```
|
|
237
283
|
|
|
238
284
|
You can add the following `belongs_to` options to `acts_as_tenant`:
|
|
239
|
-
`:foreign_key, :class_name, :inverse_of, :optional, :primary_key, :counter_cache`
|
|
285
|
+
`:foreign_key, :class_name, :inverse_of, :optional, :primary_key, :counter_cache, :polymorphic, :touch`
|
|
240
286
|
|
|
241
287
|
Example: `acts_as_tenant(:account, counter_cache: true)`
|
|
242
288
|
|
|
@@ -5,18 +5,19 @@ module ActsAsTenant
|
|
|
5
5
|
class_methods do
|
|
6
6
|
def acts_as_tenant(tenant = :account, **options)
|
|
7
7
|
ActsAsTenant.set_tenant_klass(tenant)
|
|
8
|
+
ActsAsTenant.mutable_tenant!(false)
|
|
8
9
|
|
|
9
10
|
ActsAsTenant.add_global_record_model(self) if options[:has_global_records]
|
|
10
11
|
|
|
11
12
|
# Create the association
|
|
12
|
-
valid_options = options.slice(:foreign_key, :class_name, :inverse_of, :optional, :primary_key, :counter_cache)
|
|
13
|
+
valid_options = options.slice(:foreign_key, :class_name, :inverse_of, :optional, :primary_key, :counter_cache, :polymorphic, :touch)
|
|
13
14
|
fkey = valid_options[:foreign_key] || ActsAsTenant.fkey
|
|
14
15
|
pkey = valid_options[:primary_key] || ActsAsTenant.pkey
|
|
15
16
|
polymorphic_type = valid_options[:foreign_type] || ActsAsTenant.polymorphic_type
|
|
16
17
|
belongs_to tenant, **valid_options
|
|
17
18
|
|
|
18
19
|
default_scope lambda {
|
|
19
|
-
if ActsAsTenant.
|
|
20
|
+
if ActsAsTenant.should_require_tenant? && ActsAsTenant.current_tenant.nil? && !ActsAsTenant.unscoped?
|
|
20
21
|
raise ActsAsTenant::Errors::NoTenantSet
|
|
21
22
|
end
|
|
22
23
|
|
|
@@ -24,9 +25,15 @@ module ActsAsTenant
|
|
|
24
25
|
keys = [ActsAsTenant.current_tenant.send(pkey)].compact
|
|
25
26
|
keys.push(nil) if options[:has_global_records]
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
if options[:through]
|
|
29
|
+
query_criteria = {options[:through] => {fkey.to_sym => keys}}
|
|
30
|
+
query_criteria[polymorphic_type.to_sym] = ActsAsTenant.current_tenant.class.to_s if options[:polymorphic]
|
|
31
|
+
joins(options[:through]).where(query_criteria)
|
|
32
|
+
else
|
|
33
|
+
query_criteria = {fkey.to_sym => keys}
|
|
34
|
+
query_criteria[polymorphic_type.to_sym] = ActsAsTenant.current_tenant.class.to_s if options[:polymorphic]
|
|
35
|
+
where(query_criteria)
|
|
36
|
+
end
|
|
30
37
|
else
|
|
31
38
|
all
|
|
32
39
|
end
|
|
@@ -71,15 +78,19 @@ module ActsAsTenant
|
|
|
71
78
|
to_include = Module.new {
|
|
72
79
|
define_method "#{fkey}=" do |integer|
|
|
73
80
|
write_attribute(fkey.to_s, integer)
|
|
74
|
-
raise ActsAsTenant::Errors::TenantIsImmutable if
|
|
81
|
+
raise ActsAsTenant::Errors::TenantIsImmutable if !ActsAsTenant.mutable_tenant? && tenant_modified?
|
|
75
82
|
integer
|
|
76
83
|
end
|
|
77
84
|
|
|
78
85
|
define_method "#{ActsAsTenant.tenant_klass}=" do |model|
|
|
79
86
|
super(model)
|
|
80
|
-
raise ActsAsTenant::Errors::TenantIsImmutable if
|
|
87
|
+
raise ActsAsTenant::Errors::TenantIsImmutable if !ActsAsTenant.mutable_tenant? && tenant_modified?
|
|
81
88
|
model
|
|
82
89
|
end
|
|
90
|
+
|
|
91
|
+
define_method :tenant_modified? do
|
|
92
|
+
will_save_change_to_attribute?(fkey) && persisted? && attribute_in_database(fkey).present?
|
|
93
|
+
end
|
|
83
94
|
}
|
|
84
95
|
include to_include
|
|
85
96
|
|
|
@@ -95,9 +106,9 @@ module ActsAsTenant
|
|
|
95
106
|
|
|
96
107
|
fkey = reflect_on_association(ActsAsTenant.tenant_klass).foreign_key
|
|
97
108
|
|
|
98
|
-
validation_args = args.
|
|
109
|
+
validation_args = args.deep_dup
|
|
99
110
|
validation_args[:scope] = if args[:scope]
|
|
100
|
-
Array(args[:scope])
|
|
111
|
+
Array(args[:scope]) + [fkey]
|
|
101
112
|
else
|
|
102
113
|
fkey
|
|
103
114
|
end
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
module ActsAsTenant::Sidekiq
|
|
2
|
+
class BaseMiddleware
|
|
3
|
+
def self.sidekiq_7_and_up?
|
|
4
|
+
Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new("7")
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
2
8
|
# Get the current tenant and store in the message to be sent to Sidekiq.
|
|
3
|
-
class Client
|
|
9
|
+
class Client < BaseMiddleware
|
|
10
|
+
include Sidekiq::ClientMiddleware if sidekiq_7_and_up?
|
|
11
|
+
|
|
4
12
|
def call(worker_class, msg, queue, redis_pool)
|
|
5
13
|
if ActsAsTenant.current_tenant.present?
|
|
6
14
|
msg["acts_as_tenant"] ||=
|
|
@@ -15,7 +23,9 @@ module ActsAsTenant::Sidekiq
|
|
|
15
23
|
end
|
|
16
24
|
|
|
17
25
|
# Pull the tenant out and run the current thread with it.
|
|
18
|
-
class Server
|
|
26
|
+
class Server < BaseMiddleware
|
|
27
|
+
include Sidekiq::ServerMiddleware if sidekiq_7_and_up?
|
|
28
|
+
|
|
19
29
|
def call(worker_class, msg, queue)
|
|
20
30
|
if msg.has_key?("acts_as_tenant")
|
|
21
31
|
account = msg["acts_as_tenant"]["class"].constantize.find msg["acts_as_tenant"]["id"]
|
data/lib/acts_as_tenant.rb
CHANGED
|
@@ -12,9 +12,9 @@ module ActsAsTenant
|
|
|
12
12
|
@@configuration = nil
|
|
13
13
|
@@tenant_klass = nil
|
|
14
14
|
@@models_with_global_records = []
|
|
15
|
+
@@mutable_tenant = false
|
|
15
16
|
|
|
16
17
|
class << self
|
|
17
|
-
attr_accessor :test_tenant
|
|
18
18
|
attr_writer :default_tenant
|
|
19
19
|
end
|
|
20
20
|
|
|
@@ -64,6 +64,14 @@ module ActsAsTenant
|
|
|
64
64
|
RequestStore.store[:current_tenant] || test_tenant || default_tenant
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
+
def self.test_tenant=(tenant)
|
|
68
|
+
Thread.current[:test_tenant] = tenant
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.test_tenant
|
|
72
|
+
Thread.current[:test_tenant]
|
|
73
|
+
end
|
|
74
|
+
|
|
67
75
|
def self.unscoped=(unscoped)
|
|
68
76
|
RequestStore.store[:acts_as_tenant_unscoped] = unscoped
|
|
69
77
|
end
|
|
@@ -80,6 +88,14 @@ module ActsAsTenant
|
|
|
80
88
|
@default_tenant unless unscoped
|
|
81
89
|
end
|
|
82
90
|
|
|
91
|
+
def self.mutable_tenant!(toggle)
|
|
92
|
+
@@mutable_tenant = toggle
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def self.mutable_tenant?
|
|
96
|
+
@@mutable_tenant
|
|
97
|
+
end
|
|
98
|
+
|
|
83
99
|
def self.with_tenant(tenant, &block)
|
|
84
100
|
if block.nil?
|
|
85
101
|
raise ArgumentError, "block required"
|
|
@@ -99,16 +115,34 @@ module ActsAsTenant
|
|
|
99
115
|
end
|
|
100
116
|
|
|
101
117
|
old_tenant = current_tenant
|
|
118
|
+
old_test_tenant = test_tenant
|
|
102
119
|
old_unscoped = unscoped
|
|
103
120
|
|
|
104
121
|
self.current_tenant = nil
|
|
122
|
+
self.test_tenant = nil
|
|
105
123
|
self.unscoped = true
|
|
106
124
|
value = block.call
|
|
107
125
|
value
|
|
108
126
|
ensure
|
|
109
127
|
self.current_tenant = old_tenant
|
|
128
|
+
self.test_tenant = old_test_tenant
|
|
110
129
|
self.unscoped = old_unscoped
|
|
111
130
|
end
|
|
131
|
+
|
|
132
|
+
def self.with_mutable_tenant(&block)
|
|
133
|
+
ActsAsTenant.mutable_tenant!(true)
|
|
134
|
+
without_tenant(&block)
|
|
135
|
+
ensure
|
|
136
|
+
ActsAsTenant.mutable_tenant!(false)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def self.should_require_tenant?
|
|
140
|
+
if configuration.require_tenant.respond_to?(:call)
|
|
141
|
+
!!configuration.require_tenant.call
|
|
142
|
+
else
|
|
143
|
+
!!configuration.require_tenant
|
|
144
|
+
end
|
|
145
|
+
end
|
|
112
146
|
end
|
|
113
147
|
|
|
114
148
|
ActiveSupport.on_load(:active_record) do |base|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: acts_as_tenant
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Erwin Matthijssen
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2023-01-23 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: request_store
|
|
@@ -153,89 +153,6 @@ files:
|
|
|
153
153
|
- lib/acts_as_tenant/tenant_helper.rb
|
|
154
154
|
- lib/acts_as_tenant/test_tenant_middleware.rb
|
|
155
155
|
- lib/acts_as_tenant/version.rb
|
|
156
|
-
- spec/acts_as_tenant/configuration_spec.rb
|
|
157
|
-
- spec/acts_as_tenant/sidekiq_spec.rb
|
|
158
|
-
- spec/controllers/filter_spec.rb
|
|
159
|
-
- spec/controllers/subdomain_or_domain_spec.rb
|
|
160
|
-
- spec/controllers/subdomain_spec.rb
|
|
161
|
-
- spec/dummy/.ruby-version
|
|
162
|
-
- spec/dummy/Rakefile
|
|
163
|
-
- spec/dummy/app/assets/config/manifest.js
|
|
164
|
-
- spec/dummy/app/assets/images/.keep
|
|
165
|
-
- spec/dummy/app/assets/stylesheets/application.css
|
|
166
|
-
- spec/dummy/app/channels/application_cable/channel.rb
|
|
167
|
-
- spec/dummy/app/channels/application_cable/connection.rb
|
|
168
|
-
- spec/dummy/app/controllers/application_controller.rb
|
|
169
|
-
- spec/dummy/app/controllers/concerns/.keep
|
|
170
|
-
- spec/dummy/app/helpers/application_helper.rb
|
|
171
|
-
- spec/dummy/app/javascript/packs/application.js
|
|
172
|
-
- spec/dummy/app/jobs/application_job.rb
|
|
173
|
-
- spec/dummy/app/mailers/application_mailer.rb
|
|
174
|
-
- spec/dummy/app/mailers/user_mailer.rb
|
|
175
|
-
- spec/dummy/app/models/account.rb
|
|
176
|
-
- spec/dummy/app/models/aliased_task.rb
|
|
177
|
-
- spec/dummy/app/models/article.rb
|
|
178
|
-
- spec/dummy/app/models/comment.rb
|
|
179
|
-
- spec/dummy/app/models/concerns/.keep
|
|
180
|
-
- spec/dummy/app/models/custom_counter_cache_task.rb
|
|
181
|
-
- spec/dummy/app/models/custom_foreign_key_task.rb
|
|
182
|
-
- spec/dummy/app/models/custom_primary_key_task.rb
|
|
183
|
-
- spec/dummy/app/models/global_project.rb
|
|
184
|
-
- spec/dummy/app/models/global_project_with_conditions.rb
|
|
185
|
-
- spec/dummy/app/models/global_project_with_if.rb
|
|
186
|
-
- spec/dummy/app/models/manager.rb
|
|
187
|
-
- spec/dummy/app/models/polymorphic_tenant_comment.rb
|
|
188
|
-
- spec/dummy/app/models/project.rb
|
|
189
|
-
- spec/dummy/app/models/task.rb
|
|
190
|
-
- spec/dummy/app/models/unique_task.rb
|
|
191
|
-
- spec/dummy/app/models/unscoped_model.rb
|
|
192
|
-
- spec/dummy/app/views/layouts/application.html.erb
|
|
193
|
-
- spec/dummy/app/views/layouts/mailer.html.erb
|
|
194
|
-
- spec/dummy/app/views/layouts/mailer.text.erb
|
|
195
|
-
- spec/dummy/bin/rails
|
|
196
|
-
- spec/dummy/bin/rake
|
|
197
|
-
- spec/dummy/bin/setup
|
|
198
|
-
- spec/dummy/config.ru
|
|
199
|
-
- spec/dummy/config/application.rb
|
|
200
|
-
- spec/dummy/config/boot.rb
|
|
201
|
-
- spec/dummy/config/cable.yml
|
|
202
|
-
- spec/dummy/config/database.yml
|
|
203
|
-
- spec/dummy/config/environment.rb
|
|
204
|
-
- spec/dummy/config/environments/development.rb
|
|
205
|
-
- spec/dummy/config/environments/production.rb
|
|
206
|
-
- spec/dummy/config/environments/test.rb
|
|
207
|
-
- spec/dummy/config/initializers/application_controller_renderer.rb
|
|
208
|
-
- spec/dummy/config/initializers/assets.rb
|
|
209
|
-
- spec/dummy/config/initializers/backtrace_silencers.rb
|
|
210
|
-
- spec/dummy/config/initializers/content_security_policy.rb
|
|
211
|
-
- spec/dummy/config/initializers/cookies_serializer.rb
|
|
212
|
-
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
|
213
|
-
- spec/dummy/config/initializers/inflections.rb
|
|
214
|
-
- spec/dummy/config/initializers/mime_types.rb
|
|
215
|
-
- spec/dummy/config/initializers/wrap_parameters.rb
|
|
216
|
-
- spec/dummy/config/locales/en.yml
|
|
217
|
-
- spec/dummy/config/puma.rb
|
|
218
|
-
- spec/dummy/config/routes.rb
|
|
219
|
-
- spec/dummy/config/spring.rb
|
|
220
|
-
- spec/dummy/config/storage.yml
|
|
221
|
-
- spec/dummy/db/schema.rb
|
|
222
|
-
- spec/dummy/lib/assets/.keep
|
|
223
|
-
- spec/dummy/log/.keep
|
|
224
|
-
- spec/dummy/public/404.html
|
|
225
|
-
- spec/dummy/public/422.html
|
|
226
|
-
- spec/dummy/public/500.html
|
|
227
|
-
- spec/dummy/public/apple-touch-icon-precomposed.png
|
|
228
|
-
- spec/dummy/public/apple-touch-icon.png
|
|
229
|
-
- spec/dummy/public/favicon.ico
|
|
230
|
-
- spec/dummy/tmp/development_secret.txt
|
|
231
|
-
- spec/fixtures/accounts.yml
|
|
232
|
-
- spec/fixtures/custom_primary_key_tasks.yml
|
|
233
|
-
- spec/fixtures/global_projects.yml
|
|
234
|
-
- spec/fixtures/projects.yml
|
|
235
|
-
- spec/helpers/tenant_helper_spec.rb
|
|
236
|
-
- spec/middlewares/test_tenant_middleware_spec.rb
|
|
237
|
-
- spec/models/model_extensions_spec.rb
|
|
238
|
-
- spec/spec_helper.rb
|
|
239
156
|
homepage: https://github.com/ErwinM/acts_as_tenant
|
|
240
157
|
licenses: []
|
|
241
158
|
metadata: {}
|
|
@@ -254,91 +171,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
254
171
|
- !ruby/object:Gem::Version
|
|
255
172
|
version: '0'
|
|
256
173
|
requirements: []
|
|
257
|
-
rubygems_version: 3.
|
|
174
|
+
rubygems_version: 3.4.4
|
|
258
175
|
signing_key:
|
|
259
176
|
specification_version: 4
|
|
260
177
|
summary: Add multi-tenancy to Rails applications using a shared db strategy
|
|
261
|
-
test_files:
|
|
262
|
-
- spec/acts_as_tenant/configuration_spec.rb
|
|
263
|
-
- spec/acts_as_tenant/sidekiq_spec.rb
|
|
264
|
-
- spec/controllers/filter_spec.rb
|
|
265
|
-
- spec/controllers/subdomain_or_domain_spec.rb
|
|
266
|
-
- spec/controllers/subdomain_spec.rb
|
|
267
|
-
- spec/dummy/.ruby-version
|
|
268
|
-
- spec/dummy/Rakefile
|
|
269
|
-
- spec/dummy/app/assets/config/manifest.js
|
|
270
|
-
- spec/dummy/app/assets/images/.keep
|
|
271
|
-
- spec/dummy/app/assets/stylesheets/application.css
|
|
272
|
-
- spec/dummy/app/channels/application_cable/channel.rb
|
|
273
|
-
- spec/dummy/app/channels/application_cable/connection.rb
|
|
274
|
-
- spec/dummy/app/controllers/application_controller.rb
|
|
275
|
-
- spec/dummy/app/controllers/concerns/.keep
|
|
276
|
-
- spec/dummy/app/helpers/application_helper.rb
|
|
277
|
-
- spec/dummy/app/javascript/packs/application.js
|
|
278
|
-
- spec/dummy/app/jobs/application_job.rb
|
|
279
|
-
- spec/dummy/app/mailers/application_mailer.rb
|
|
280
|
-
- spec/dummy/app/mailers/user_mailer.rb
|
|
281
|
-
- spec/dummy/app/models/account.rb
|
|
282
|
-
- spec/dummy/app/models/aliased_task.rb
|
|
283
|
-
- spec/dummy/app/models/article.rb
|
|
284
|
-
- spec/dummy/app/models/comment.rb
|
|
285
|
-
- spec/dummy/app/models/concerns/.keep
|
|
286
|
-
- spec/dummy/app/models/custom_counter_cache_task.rb
|
|
287
|
-
- spec/dummy/app/models/custom_foreign_key_task.rb
|
|
288
|
-
- spec/dummy/app/models/custom_primary_key_task.rb
|
|
289
|
-
- spec/dummy/app/models/global_project.rb
|
|
290
|
-
- spec/dummy/app/models/global_project_with_conditions.rb
|
|
291
|
-
- spec/dummy/app/models/global_project_with_if.rb
|
|
292
|
-
- spec/dummy/app/models/manager.rb
|
|
293
|
-
- spec/dummy/app/models/polymorphic_tenant_comment.rb
|
|
294
|
-
- spec/dummy/app/models/project.rb
|
|
295
|
-
- spec/dummy/app/models/task.rb
|
|
296
|
-
- spec/dummy/app/models/unique_task.rb
|
|
297
|
-
- spec/dummy/app/models/unscoped_model.rb
|
|
298
|
-
- spec/dummy/app/views/layouts/application.html.erb
|
|
299
|
-
- spec/dummy/app/views/layouts/mailer.html.erb
|
|
300
|
-
- spec/dummy/app/views/layouts/mailer.text.erb
|
|
301
|
-
- spec/dummy/bin/rails
|
|
302
|
-
- spec/dummy/bin/rake
|
|
303
|
-
- spec/dummy/bin/setup
|
|
304
|
-
- spec/dummy/config.ru
|
|
305
|
-
- spec/dummy/config/application.rb
|
|
306
|
-
- spec/dummy/config/boot.rb
|
|
307
|
-
- spec/dummy/config/cable.yml
|
|
308
|
-
- spec/dummy/config/database.yml
|
|
309
|
-
- spec/dummy/config/environment.rb
|
|
310
|
-
- spec/dummy/config/environments/development.rb
|
|
311
|
-
- spec/dummy/config/environments/production.rb
|
|
312
|
-
- spec/dummy/config/environments/test.rb
|
|
313
|
-
- spec/dummy/config/initializers/application_controller_renderer.rb
|
|
314
|
-
- spec/dummy/config/initializers/assets.rb
|
|
315
|
-
- spec/dummy/config/initializers/backtrace_silencers.rb
|
|
316
|
-
- spec/dummy/config/initializers/content_security_policy.rb
|
|
317
|
-
- spec/dummy/config/initializers/cookies_serializer.rb
|
|
318
|
-
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
|
319
|
-
- spec/dummy/config/initializers/inflections.rb
|
|
320
|
-
- spec/dummy/config/initializers/mime_types.rb
|
|
321
|
-
- spec/dummy/config/initializers/wrap_parameters.rb
|
|
322
|
-
- spec/dummy/config/locales/en.yml
|
|
323
|
-
- spec/dummy/config/puma.rb
|
|
324
|
-
- spec/dummy/config/routes.rb
|
|
325
|
-
- spec/dummy/config/spring.rb
|
|
326
|
-
- spec/dummy/config/storage.yml
|
|
327
|
-
- spec/dummy/db/schema.rb
|
|
328
|
-
- spec/dummy/lib/assets/.keep
|
|
329
|
-
- spec/dummy/log/.keep
|
|
330
|
-
- spec/dummy/public/404.html
|
|
331
|
-
- spec/dummy/public/422.html
|
|
332
|
-
- spec/dummy/public/500.html
|
|
333
|
-
- spec/dummy/public/apple-touch-icon-precomposed.png
|
|
334
|
-
- spec/dummy/public/apple-touch-icon.png
|
|
335
|
-
- spec/dummy/public/favicon.ico
|
|
336
|
-
- spec/dummy/tmp/development_secret.txt
|
|
337
|
-
- spec/fixtures/accounts.yml
|
|
338
|
-
- spec/fixtures/custom_primary_key_tasks.yml
|
|
339
|
-
- spec/fixtures/global_projects.yml
|
|
340
|
-
- spec/fixtures/projects.yml
|
|
341
|
-
- spec/helpers/tenant_helper_spec.rb
|
|
342
|
-
- spec/middlewares/test_tenant_middleware_spec.rb
|
|
343
|
-
- spec/models/model_extensions_spec.rb
|
|
344
|
-
- spec/spec_helper.rb
|
|
178
|
+
test_files: []
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
describe ActsAsTenant::Configuration do
|
|
4
|
-
after { ActsAsTenant.configure }
|
|
5
|
-
|
|
6
|
-
it "provides defaults" do
|
|
7
|
-
expect(ActsAsTenant.configuration.require_tenant).not_to be_truthy
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it "stores config" do
|
|
11
|
-
ActsAsTenant.configure do |config|
|
|
12
|
-
config.require_tenant = true
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
expect(ActsAsTenant.configuration.require_tenant).to eq(true)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require "sidekiq"
|
|
3
|
-
require "acts_as_tenant/sidekiq"
|
|
4
|
-
|
|
5
|
-
describe ActsAsTenant::Sidekiq do
|
|
6
|
-
let(:account) { Account.new(id: 1234) }
|
|
7
|
-
let(:message) { {"acts_as_tenant" => {"class" => "Account", "id" => 1234}} }
|
|
8
|
-
|
|
9
|
-
describe ActsAsTenant::Sidekiq::Client do
|
|
10
|
-
subject { ActsAsTenant::Sidekiq::Client.new }
|
|
11
|
-
|
|
12
|
-
it "saves tenant if present" do
|
|
13
|
-
ActsAsTenant.current_tenant = account
|
|
14
|
-
|
|
15
|
-
msg = {}
|
|
16
|
-
subject.call(nil, msg, nil, nil) {}
|
|
17
|
-
expect(msg).to eq message
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "does not set tenant if not present" do
|
|
21
|
-
expect(ActsAsTenant.current_tenant).to be_nil
|
|
22
|
-
|
|
23
|
-
msg = {}
|
|
24
|
-
subject.call(nil, msg, nil, nil) {}
|
|
25
|
-
expect(msg).not_to eq message
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
describe ActsAsTenant::Sidekiq::Server do
|
|
30
|
-
subject { ActsAsTenant::Sidekiq::Server.new }
|
|
31
|
-
|
|
32
|
-
it "restores tenant if tenant saved" do
|
|
33
|
-
expect(Account).to receive(:find).with(1234).once { account }
|
|
34
|
-
|
|
35
|
-
msg = message
|
|
36
|
-
subject.call(nil, msg, nil) do
|
|
37
|
-
expect(ActsAsTenant.current_tenant).to be_a_kind_of Account
|
|
38
|
-
end
|
|
39
|
-
expect(ActsAsTenant.current_tenant).to be_nil
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it "runs without tenant if no tenant saved" do
|
|
43
|
-
expect(Account).not_to receive(:find)
|
|
44
|
-
|
|
45
|
-
msg = {}
|
|
46
|
-
subject.call(nil, msg, nil) do
|
|
47
|
-
expect(ActsAsTenant.current_tenant).to be_nil
|
|
48
|
-
end
|
|
49
|
-
expect(ActsAsTenant.current_tenant).to be_nil
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
it "includes ActsAsTenant client middleware" do
|
|
54
|
-
expect(Sidekiq.client_middleware.exists?(ActsAsTenant::Sidekiq::Client)).to eq(true)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# unable to test server configuration
|
|
58
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
class ApplicationController2 < ActionController::Base
|
|
4
|
-
include Rails.application.routes.url_helpers
|
|
5
|
-
set_current_tenant_through_filter
|
|
6
|
-
before_action :your_method_that_finds_the_current_tenant
|
|
7
|
-
|
|
8
|
-
def your_method_that_finds_the_current_tenant
|
|
9
|
-
current_account = Account.new(name: "account1")
|
|
10
|
-
set_current_tenant(current_account)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# Start testing
|
|
15
|
-
describe ApplicationController2, type: :controller do
|
|
16
|
-
controller do
|
|
17
|
-
def index
|
|
18
|
-
# Exercise current_tenant helper method
|
|
19
|
-
render plain: current_tenant.name
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "Finds the correct tenant using the filter command" do
|
|
24
|
-
get :index
|
|
25
|
-
expect(ActsAsTenant.current_tenant.name).to eq "account1"
|
|
26
|
-
expect(response.body).to eq "account1"
|
|
27
|
-
end
|
|
28
|
-
end
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
class DomainController < ActionController::Base
|
|
4
|
-
include Rails.application.routes.url_helpers
|
|
5
|
-
set_current_tenant_by_subdomain_or_domain
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
describe DomainController, type: :controller do
|
|
9
|
-
let(:account) { accounts(:with_domain) }
|
|
10
|
-
|
|
11
|
-
controller do
|
|
12
|
-
def index
|
|
13
|
-
# Exercise current_tenant helper method
|
|
14
|
-
render plain: current_tenant.name
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it "finds the correct tenant with a example1.com" do
|
|
19
|
-
@request.host = account.domain
|
|
20
|
-
get :index
|
|
21
|
-
expect(ActsAsTenant.current_tenant).to eq account
|
|
22
|
-
expect(response.body).to eq account.name
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it "finds the correct tenant with a subdomain.example.com" do
|
|
26
|
-
@request.host = "#{account.subdomain}.example.com"
|
|
27
|
-
get :index
|
|
28
|
-
expect(ActsAsTenant.current_tenant).to eq account
|
|
29
|
-
expect(response.body).to eq account.name
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it "finds the correct tenant with a www.subdomain.example.com" do
|
|
33
|
-
@request.host = "www.#{account.subdomain}.example.com"
|
|
34
|
-
get :index
|
|
35
|
-
expect(ActsAsTenant.current_tenant).to eq account
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
it "ignores case when finding tenant by subdomain" do
|
|
39
|
-
@request.host = "#{account.subdomain.upcase}.example.com"
|
|
40
|
-
get :index
|
|
41
|
-
expect(ActsAsTenant.current_tenant).to eq account
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
context "overriding subdomain lookup" do
|
|
45
|
-
after { controller.subdomain_lookup = :last }
|
|
46
|
-
|
|
47
|
-
it "allows overriding the subdomain lookup" do
|
|
48
|
-
controller.subdomain_lookup = :first
|
|
49
|
-
@request.host = "#{account.subdomain}.another.example.com"
|
|
50
|
-
get :index
|
|
51
|
-
expect(ActsAsTenant.current_tenant).to eq account
|
|
52
|
-
expect(response.body).to eq(account.subdomain)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|