rails_multisite 2.1.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rails_multisite might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +13 -0
- data/lib/rails_multisite/connection_management.rb +74 -38
- data/lib/rails_multisite/connection_management/rails_60_compat.rb +29 -0
- data/lib/rails_multisite/connection_management/rails_61_compat.rb +37 -0
- data/lib/rails_multisite/version.rb +1 -1
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee4885d481591f47f16a367e206e103af5ef3ea1504d65e0c34f97fa8766b91f
|
4
|
+
data.tar.gz: b6dc6f7d07e5ced80e7da754f5940b30a42a60d02e859afc8c949ffdf24f8b60
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9d34362e98ddce5e8f771233ad43a803cf66e71bcd546dedaee3ae4a06991149f2e07d9e6024cbc111ee3166db7c193772cfdf7c78bec729da772b5db06a5bf
|
7
|
+
data.tar.gz: 4c9fdee8046e62e40be983d6f28f8e0fc703f89129e3d41d7ee9003aefa1c344bd170b7d4a5c1575729b80363ee2a7cfb48ad6a299564db3aa52da2fef0090c4
|
data/README.md
CHANGED
@@ -93,6 +93,19 @@ To get a Rails console that is connected to `some_database_1` database:
|
|
93
93
|
RAILS_DB=db_one rails console
|
94
94
|
```
|
95
95
|
|
96
|
+
### CDN origin support
|
97
|
+
|
98
|
+
To avoid needing to configure many origins you can consider using `RailsMultisite::ConnectionManagement.asset_hostnames`
|
99
|
+
|
100
|
+
When configured, requests to `asset_hostname`?__ws=another.host.name will be re-routed to the correct site. Cookies will
|
101
|
+
be stripped on all incoming requests.
|
102
|
+
|
103
|
+
Example:
|
104
|
+
|
105
|
+
- Multisite serves `sub.example.com` and `assets.example.com`
|
106
|
+
- `RailsMultisite::ConnectionManagement.asset_hostnames = ['assets.example.com']`
|
107
|
+
- Requests to `https://assets.example.com/route/?__ws=sub.example.com` will be routed to the `sub.example.com`
|
108
|
+
|
96
109
|
|
97
110
|
## Contributing
|
98
111
|
|
@@ -1,16 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
if Rails.version >= '6.1'
|
4
|
+
require 'rails_multisite/connection_management/rails_61_compat'
|
5
|
+
else
|
6
|
+
require 'rails_multisite/connection_management/rails_60_compat'
|
7
|
+
end
|
8
|
+
|
3
9
|
module RailsMultisite
|
4
10
|
class ConnectionManagement
|
5
|
-
|
6
11
|
DEFAULT = 'default'
|
7
|
-
SPEC_KLASS = ActiveRecord::ConnectionAdapters::ConnectionSpecification
|
8
12
|
|
9
13
|
def self.default_config_filename
|
10
14
|
File.absolute_path(Rails.root.to_s + "/config/multisite.yml")
|
11
15
|
end
|
12
16
|
|
13
17
|
def self.clear_settings!
|
18
|
+
@instance&.db_spec_cache&.each do |key, spec|
|
19
|
+
@instance.connection_handlers.delete(self.handler_key(spec))
|
20
|
+
end
|
21
|
+
|
14
22
|
@instance = nil
|
15
23
|
end
|
16
24
|
|
@@ -31,6 +39,14 @@ module RailsMultisite
|
|
31
39
|
end
|
32
40
|
end
|
33
41
|
|
42
|
+
def self.asset_hostnames
|
43
|
+
@asset_hostnames
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.asset_hostnames=(h)
|
47
|
+
@asset_hostnames = h
|
48
|
+
end
|
49
|
+
|
34
50
|
def self.config_filename
|
35
51
|
@instance.config_filename
|
36
52
|
end
|
@@ -92,16 +108,11 @@ module RailsMultisite
|
|
92
108
|
end
|
93
109
|
|
94
110
|
def self.current_hostname
|
95
|
-
|
96
|
-
spec ||= ActiveRecord::Base.connection_pool.spec
|
97
|
-
config = spec.config
|
98
|
-
config[:host_names].nil? ? config[:host] : config[:host_names].first
|
111
|
+
current_db_hostnames.first
|
99
112
|
end
|
100
113
|
|
101
114
|
def self.current_db_hostnames
|
102
|
-
|
103
|
-
spec ||= ActiveRecord::Base.connection_pool.spec
|
104
|
-
config = spec.config
|
115
|
+
config = (@instance&.connection_spec(db: current_db) || ConnectionSpecification.current).config
|
105
116
|
config[:host_names].nil? ? [config[:host]] : config[:host_names]
|
106
117
|
end
|
107
118
|
|
@@ -109,7 +120,7 @@ module RailsMultisite
|
|
109
120
|
if @instance
|
110
121
|
@instance.connection_spec(opts)
|
111
122
|
else
|
112
|
-
|
123
|
+
ConnectionSpecification.current
|
113
124
|
end
|
114
125
|
end
|
115
126
|
|
@@ -121,17 +132,45 @@ module RailsMultisite
|
|
121
132
|
end
|
122
133
|
end
|
123
134
|
|
124
|
-
|
135
|
+
def self.handler_key(spec)
|
136
|
+
@handler_key_suffix ||= begin
|
137
|
+
if ActiveRecord::Base.respond_to?(:writing_role)
|
138
|
+
"_#{ActiveRecord::Base.writing_role}"
|
139
|
+
else
|
140
|
+
""
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
:"#{spec.name}#{@handler_key_suffix}"
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.default_connection_handler=(connection_handler)
|
148
|
+
if @instance
|
149
|
+
unless connection_handler.is_a?(ActiveRecord::ConnectionAdapters::ConnectionHandler)
|
150
|
+
raise ArgumentError.new("Invalid connection handler")
|
151
|
+
end
|
152
|
+
|
153
|
+
@instance.default_connection_handler = connection_handler
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
attr_reader :config_filename, :db_spec_cache, :connection_handlers
|
158
|
+
attr_writer :default_connection_handler
|
125
159
|
|
126
160
|
def initialize(config_filename)
|
127
161
|
@config_filename = config_filename
|
128
162
|
|
129
|
-
@connection_handlers =
|
130
|
-
|
163
|
+
@connection_handlers = begin
|
164
|
+
if ActiveRecord::Base.respond_to?(:connection_handlers)
|
165
|
+
ActiveRecord::Base.connection_handlers
|
166
|
+
else
|
167
|
+
{}
|
168
|
+
end
|
169
|
+
end
|
131
170
|
|
132
|
-
@
|
171
|
+
@db_spec_cache = {}
|
172
|
+
@default_spec = ConnectionSpecification.default
|
133
173
|
@default_connection_handler = ActiveRecord::Base.connection_handler
|
134
|
-
@established_default = false
|
135
174
|
|
136
175
|
@reload_mutex = Mutex.new
|
137
176
|
|
@@ -141,7 +180,7 @@ module RailsMultisite
|
|
141
180
|
def load_config!
|
142
181
|
configs = YAML::load(File.open(@config_filename))
|
143
182
|
|
144
|
-
no_prepared_statements =
|
183
|
+
no_prepared_statements = @default_spec.config[:prepared_statements] == false
|
145
184
|
|
146
185
|
configs.each do |k, v|
|
147
186
|
raise ArgumentError.new("Please do not name any db default!") if k == DEFAULT
|
@@ -149,17 +188,8 @@ module RailsMultisite
|
|
149
188
|
v[:prepared_statements] = false if no_prepared_statements
|
150
189
|
end
|
151
190
|
|
152
|
-
resolve_configs = configs
|
153
|
-
|
154
|
-
# rails 6 needs to use a proper object for the resolver
|
155
|
-
if defined?(ActiveRecord::DatabaseConfigurations)
|
156
|
-
resolve_configs = ActiveRecord::DatabaseConfigurations.new(configs)
|
157
|
-
end
|
158
|
-
|
159
|
-
resolver = SPEC_KLASS::Resolver.new(resolve_configs)
|
160
|
-
|
161
191
|
# Build a hash of db name => spec
|
162
|
-
new_db_spec_cache =
|
192
|
+
new_db_spec_cache = ConnectionSpecification.db_spec_cache(configs)
|
163
193
|
new_db_spec_cache.each do |k, v|
|
164
194
|
# If spec already existed, use the old version
|
165
195
|
if v&.to_hash == @db_spec_cache[k]&.to_hash
|
@@ -177,7 +207,7 @@ module RailsMultisite
|
|
177
207
|
end
|
178
208
|
|
179
209
|
# Add the default hostnames as well
|
180
|
-
|
210
|
+
@default_spec.config[:host_names].each do |host|
|
181
211
|
new_host_spec_cache[host] = @default_spec
|
182
212
|
end
|
183
213
|
|
@@ -188,8 +218,7 @@ module RailsMultisite
|
|
188
218
|
@db_spec_cache = new_db_spec_cache
|
189
219
|
|
190
220
|
# Clean up connection handler cache.
|
191
|
-
|
192
|
-
removed_specs.each { |s| @connection_handlers.delete(s) }
|
221
|
+
removed_specs.each { |s| @connection_handlers.delete(handler_key(s)) }
|
193
222
|
end
|
194
223
|
|
195
224
|
def reload
|
@@ -217,18 +246,14 @@ module RailsMultisite
|
|
217
246
|
spec ||= @default_spec
|
218
247
|
handler = nil
|
219
248
|
if spec != @default_spec
|
220
|
-
handler = @connection_handlers[spec]
|
249
|
+
handler = @connection_handlers[handler_key(spec)]
|
221
250
|
unless handler
|
222
251
|
handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
|
223
252
|
handler_establish_connection(handler, spec)
|
224
|
-
@connection_handlers[spec] = handler
|
253
|
+
@connection_handlers[handler_key(spec)] = handler
|
225
254
|
end
|
226
255
|
else
|
227
256
|
handler = @default_connection_handler
|
228
|
-
if !@established_default
|
229
|
-
handler_establish_connection(handler, spec)
|
230
|
-
@established_default = true
|
231
|
-
end
|
232
257
|
end
|
233
258
|
|
234
259
|
ActiveRecord::Base.connection_handler = handler
|
@@ -330,7 +355,7 @@ module RailsMultisite
|
|
330
355
|
end
|
331
356
|
|
332
357
|
def current_db
|
333
|
-
|
358
|
+
ConnectionSpecification.current.config[:db_key] || DEFAULT
|
334
359
|
end
|
335
360
|
|
336
361
|
def current_hostname
|
@@ -343,7 +368,14 @@ module RailsMultisite
|
|
343
368
|
end
|
344
369
|
|
345
370
|
request = Rack::Request.new(env)
|
346
|
-
|
371
|
+
|
372
|
+
host =
|
373
|
+
if request['__ws'] && self.class.asset_hostnames&.include?(request.host)
|
374
|
+
request.cookies.clear
|
375
|
+
request['__ws']
|
376
|
+
else
|
377
|
+
request.host
|
378
|
+
end
|
347
379
|
|
348
380
|
env["RAILS_MULTISITE_HOST"] = host
|
349
381
|
end
|
@@ -362,5 +394,9 @@ module RailsMultisite
|
|
362
394
|
handler.establish_connection(spec.config)
|
363
395
|
end
|
364
396
|
|
397
|
+
def handler_key(spec)
|
398
|
+
self.class.handler_key(spec)
|
399
|
+
end
|
400
|
+
|
365
401
|
end
|
366
402
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsMultisite
|
4
|
+
class ConnectionManagement
|
5
|
+
class ConnectionSpecification
|
6
|
+
class << self
|
7
|
+
def current
|
8
|
+
ActiveRecord::Base.connection_pool.spec
|
9
|
+
end
|
10
|
+
|
11
|
+
def db_spec_cache(configs)
|
12
|
+
resolve_configs = configs
|
13
|
+
# rails 6 needs to use a proper object for the resolver
|
14
|
+
if defined?(ActiveRecord::DatabaseConfigurations)
|
15
|
+
resolve_configs = ActiveRecord::DatabaseConfigurations.new(configs)
|
16
|
+
end
|
17
|
+
resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(resolve_configs)
|
18
|
+
configs.map { |k, _| [k, resolver.spec(k.to_sym)] }.to_h
|
19
|
+
end
|
20
|
+
|
21
|
+
def default
|
22
|
+
ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver
|
23
|
+
.new(ActiveRecord::Base.configurations)
|
24
|
+
.spec(Rails.env.to_sym)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsMultisite
|
4
|
+
class ConnectionManagement
|
5
|
+
class ConnectionSpecification
|
6
|
+
class << self
|
7
|
+
def current
|
8
|
+
new(ActiveRecord::Base.connection_pool.db_config)
|
9
|
+
end
|
10
|
+
|
11
|
+
def db_spec_cache(configs)
|
12
|
+
resolve_configs = ActiveRecord::DatabaseConfigurations.new(configs)
|
13
|
+
configs.map { |k, _| [k, new(resolve_configs.resolve(k.to_sym))] }.to_h
|
14
|
+
end
|
15
|
+
|
16
|
+
def default
|
17
|
+
new(ActiveRecord::Base.configurations.resolve(Rails.env.to_sym))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :spec
|
22
|
+
|
23
|
+
def initialize(spec)
|
24
|
+
@spec = spec
|
25
|
+
end
|
26
|
+
|
27
|
+
def name
|
28
|
+
spec.env_name
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_hash
|
32
|
+
spec.configuration_hash
|
33
|
+
end
|
34
|
+
alias config to_hash
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_multisite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -61,6 +61,8 @@ files:
|
|
61
61
|
- README.md
|
62
62
|
- lib/rails_multisite.rb
|
63
63
|
- lib/rails_multisite/connection_management.rb
|
64
|
+
- lib/rails_multisite/connection_management/rails_60_compat.rb
|
65
|
+
- lib/rails_multisite/connection_management/rails_61_compat.rb
|
64
66
|
- lib/rails_multisite/formatter.rb
|
65
67
|
- lib/rails_multisite/middleware.rb
|
66
68
|
- lib/rails_multisite/railtie.rb
|
@@ -70,7 +72,7 @@ files:
|
|
70
72
|
homepage: ''
|
71
73
|
licenses: []
|
72
74
|
metadata: {}
|
73
|
-
post_install_message:
|
75
|
+
post_install_message:
|
74
76
|
rdoc_options: []
|
75
77
|
require_paths:
|
76
78
|
- lib
|
@@ -85,8 +87,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
87
|
- !ruby/object:Gem::Version
|
86
88
|
version: '0'
|
87
89
|
requirements: []
|
88
|
-
rubygems_version: 3.
|
89
|
-
signing_key:
|
90
|
+
rubygems_version: 3.2.2
|
91
|
+
signing_key:
|
90
92
|
specification_version: 4
|
91
93
|
summary: Multi tenancy support for Rails
|
92
94
|
test_files: []
|