activerecord-multi-tenant 0.7.0 → 0.8.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.
- checksums.yaml +4 -4
- data/.travis.yml +5 -14
- data/Appraisals +0 -5
- data/CHANGELOG.md +13 -0
- data/Gemfile.lock +15 -3
- data/README.md +2 -2
- data/activerecord-multi-tenant.gemspec +2 -0
- data/gemfiles/active_record_5.1.gemfile.lock +16 -4
- data/gemfiles/rails_4.0.gemfile.lock +15 -2
- data/gemfiles/rails_4.1.gemfile.lock +15 -2
- data/gemfiles/rails_4.2.gemfile.lock +15 -2
- data/gemfiles/rails_5.0.gemfile.lock +14 -2
- data/gemfiles/rails_5.1.gemfile.lock +14 -2
- data/lib/activerecord-multi-tenant/query_monitor.rb +1 -1
- data/lib/activerecord-multi-tenant/query_rewriter.rb +167 -59
- data/lib/activerecord-multi-tenant/version.rb +1 -1
- data/spec/activerecord-multi-tenant/controller_extensions_spec.rb +1 -5
- data/spec/activerecord-multi-tenant/model_extensions_spec.rb +65 -2
- data/spec/activerecord-multi-tenant/record_finding_spec.rb +8 -0
- data/spec/schema.rb +23 -12
- data/spec/spec_helper.rb +3 -0
- metadata +30 -4
- data/gemfiles/rails_3.2.gemfile +0 -9
- data/gemfiles/rails_3.2.gemfile.lock +0 -145
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 37f0a1949a56f1bf5bbf3c5e4e00f0e5afdc87f8
|
|
4
|
+
data.tar.gz: bcf4da0d8b2228a3cac88ca747286beabfb543c8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 54f89ab0a2b8b648a55be5de6e31fbf7acbafb125f530348bc30b0e1ddde48444a0be30aa60c54ee17e075fbc0f868aae45b94277daf977e1d0160385fe1d426
|
|
7
|
+
data.tar.gz: 60483177cedff455c9faafdfe6f3370cfd09ab90bbb5c5ed10a1c4b71c606c425f325611c063f77441d0647b66093fc30661b8bba7ee346121acb98bd8a18fab
|
data/.travis.yml
CHANGED
|
@@ -4,12 +4,11 @@ cache: bundler
|
|
|
4
4
|
language: ruby
|
|
5
5
|
|
|
6
6
|
rvm:
|
|
7
|
-
- 2.
|
|
8
|
-
- 2.3.
|
|
9
|
-
- 2.4.
|
|
7
|
+
- 2.2.7
|
|
8
|
+
- 2.3.4
|
|
9
|
+
- 2.4.1
|
|
10
10
|
|
|
11
11
|
gemfile:
|
|
12
|
-
- gemfiles/rails_3.2.gemfile
|
|
13
12
|
- gemfiles/rails_4.0.gemfile
|
|
14
13
|
- gemfiles/rails_4.1.gemfile
|
|
15
14
|
- gemfiles/rails_4.2.gemfile
|
|
@@ -20,17 +19,9 @@ gemfile:
|
|
|
20
19
|
matrix:
|
|
21
20
|
fast_finish: true
|
|
22
21
|
exclude:
|
|
23
|
-
- rvm: 2.1
|
|
24
|
-
gemfile: gemfiles/rails_5.0.gemfile
|
|
25
|
-
- rvm: 2.1
|
|
26
|
-
gemfile: gemfiles/rails_5.1.gemfile
|
|
27
|
-
- rvm: 2.1
|
|
28
|
-
gemfile: gemfiles/active_record_5.1.gemfile
|
|
29
|
-
- rvm: 2.4.0
|
|
30
|
-
gemfile: gemfiles/rails_3.2.gemfile
|
|
31
|
-
- rvm: 2.4.0
|
|
22
|
+
- rvm: 2.4.1
|
|
32
23
|
gemfile: gemfiles/rails_4.0.gemfile
|
|
33
|
-
- rvm: 2.4.
|
|
24
|
+
- rvm: 2.4.1
|
|
34
25
|
gemfile: gemfiles/rails_4.1.gemfile
|
|
35
26
|
|
|
36
27
|
services:
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.0 2017-08-16
|
|
4
|
+
|
|
5
|
+
* Significant improvements and simplifications of query rewriting
|
|
6
|
+
* Big thanks to [Kyle Bock](https://github.com/kwbock) and [Ben Olive](https://github.com/sionide21)
|
|
7
|
+
for (re-)writing this code and verifying it works well
|
|
8
|
+
* This fixes caching issues across multiple MultiTenant.with { } blocks when
|
|
9
|
+
interacting with the Rails statement cache
|
|
10
|
+
* Drop support for Rails 3.2
|
|
11
|
+
* The arel version used in Rails 3.2 has caused more trouble than its worth -
|
|
12
|
+
it seems less troublesome to ask any users of this library to upgrade to at
|
|
13
|
+
least Rails 4.0
|
|
14
|
+
|
|
15
|
+
|
|
3
16
|
## 0.7.0 2017-07-18
|
|
4
17
|
|
|
5
18
|
* Switch back to Relation-based mechanism of hooking into ActiveRecord (this resolves issues for simple queries that didn't get rewritten)
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
activerecord-multi-tenant (0.
|
|
4
|
+
activerecord-multi-tenant (0.8.0)
|
|
5
5
|
rails (>= 3.1)
|
|
6
6
|
request_store (>= 1.0.5)
|
|
7
7
|
|
|
@@ -51,6 +51,8 @@ GEM
|
|
|
51
51
|
thor (>= 0.14.0)
|
|
52
52
|
arel (7.1.4)
|
|
53
53
|
builder (3.2.2)
|
|
54
|
+
byebug (9.0.6)
|
|
55
|
+
coderay (1.1.1)
|
|
54
56
|
concurrent-ruby (1.0.4)
|
|
55
57
|
connection_pool (2.2.1)
|
|
56
58
|
diff-lcs (1.2.5)
|
|
@@ -60,7 +62,7 @@ GEM
|
|
|
60
62
|
i18n (0.7.0)
|
|
61
63
|
loofah (2.0.3)
|
|
62
64
|
nokogiri (>= 1.5.9)
|
|
63
|
-
mail (2.6.
|
|
65
|
+
mail (2.6.6)
|
|
64
66
|
mime-types (>= 1.16, < 4)
|
|
65
67
|
method_source (0.8.2)
|
|
66
68
|
mime-types (3.1)
|
|
@@ -72,6 +74,13 @@ GEM
|
|
|
72
74
|
nokogiri (1.7.0)
|
|
73
75
|
mini_portile2 (~> 2.1.0)
|
|
74
76
|
pg (0.19.0)
|
|
77
|
+
pry (0.10.4)
|
|
78
|
+
coderay (~> 1.1.0)
|
|
79
|
+
method_source (~> 0.8.1)
|
|
80
|
+
slop (~> 3.4)
|
|
81
|
+
pry-byebug (3.4.2)
|
|
82
|
+
byebug (~> 9.0)
|
|
83
|
+
pry (~> 0.10)
|
|
75
84
|
rack (2.0.1)
|
|
76
85
|
rack-protection (1.5.3)
|
|
77
86
|
rack
|
|
@@ -129,6 +138,7 @@ GEM
|
|
|
129
138
|
connection_pool (~> 2.2, >= 2.2.0)
|
|
130
139
|
rack-protection (>= 1.5.0)
|
|
131
140
|
redis (~> 3.2, >= 3.2.1)
|
|
141
|
+
slop (3.6.0)
|
|
132
142
|
sprockets (3.7.1)
|
|
133
143
|
concurrent-ruby (~> 1.0)
|
|
134
144
|
rack (> 1, < 3)
|
|
@@ -151,6 +161,8 @@ DEPENDENCIES
|
|
|
151
161
|
activerecord-multi-tenant!
|
|
152
162
|
appraisal
|
|
153
163
|
pg
|
|
164
|
+
pry
|
|
165
|
+
pry-byebug
|
|
154
166
|
rake
|
|
155
167
|
rspec (>= 3.0)
|
|
156
168
|
rspec-rails
|
|
@@ -158,4 +170,4 @@ DEPENDENCIES
|
|
|
158
170
|
thor
|
|
159
171
|
|
|
160
172
|
BUNDLED WITH
|
|
161
|
-
1.15.
|
|
173
|
+
1.15.3
|
data/README.md
CHANGED
|
@@ -16,7 +16,7 @@ gem 'activerecord-multi-tenant'
|
|
|
16
16
|
|
|
17
17
|
## Supported Rails versions
|
|
18
18
|
|
|
19
|
-
All Ruby on Rails versions starting with
|
|
19
|
+
All Ruby on Rails versions starting with 4.0 or newer are supported.
|
|
20
20
|
|
|
21
21
|
This gem only supports ActiveRecord (the Rails default ORM), and not alternative ORMs like Sequel.
|
|
22
22
|
|
|
@@ -101,4 +101,4 @@ This gem was initially based on [acts_as_tenant](https://github.com/ErwinM/acts_
|
|
|
101
101
|
## License
|
|
102
102
|
|
|
103
103
|
Licensed under the MIT license<br>
|
|
104
|
-
Copyright (c)
|
|
104
|
+
Copyright (c) 2017, Citus Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
activerecord-multi-tenant (0.
|
|
4
|
+
activerecord-multi-tenant (0.8.0)
|
|
5
5
|
rails (>= 3.1)
|
|
6
6
|
request_store (>= 1.0.5)
|
|
7
7
|
|
|
@@ -51,6 +51,8 @@ GEM
|
|
|
51
51
|
thor (>= 0.14.0)
|
|
52
52
|
arel (8.0.0)
|
|
53
53
|
builder (3.2.3)
|
|
54
|
+
byebug (9.0.6)
|
|
55
|
+
coderay (1.1.1)
|
|
54
56
|
concurrent-ruby (1.0.5)
|
|
55
57
|
connection_pool (2.2.1)
|
|
56
58
|
diff-lcs (1.3)
|
|
@@ -60,7 +62,7 @@ GEM
|
|
|
60
62
|
i18n (0.8.1)
|
|
61
63
|
loofah (2.0.3)
|
|
62
64
|
nokogiri (>= 1.5.9)
|
|
63
|
-
mail (2.6.
|
|
65
|
+
mail (2.6.6)
|
|
64
66
|
mime-types (>= 1.16, < 4)
|
|
65
67
|
method_source (0.8.2)
|
|
66
68
|
mime-types (3.1)
|
|
@@ -68,10 +70,17 @@ GEM
|
|
|
68
70
|
mime-types-data (3.2016.0521)
|
|
69
71
|
mini_portile2 (2.1.0)
|
|
70
72
|
minitest (5.10.1)
|
|
71
|
-
nio4r (2.
|
|
73
|
+
nio4r (2.1.0)
|
|
72
74
|
nokogiri (1.7.1)
|
|
73
75
|
mini_portile2 (~> 2.1.0)
|
|
74
76
|
pg (0.20.0)
|
|
77
|
+
pry (0.10.4)
|
|
78
|
+
coderay (~> 1.1.0)
|
|
79
|
+
method_source (~> 0.8.1)
|
|
80
|
+
slop (~> 3.4)
|
|
81
|
+
pry-byebug (3.4.2)
|
|
82
|
+
byebug (~> 9.0)
|
|
83
|
+
pry (~> 0.10)
|
|
75
84
|
rack (2.0.1)
|
|
76
85
|
rack-protection (1.5.3)
|
|
77
86
|
rack
|
|
@@ -129,6 +138,7 @@ GEM
|
|
|
129
138
|
connection_pool (~> 2.2, >= 2.2.0)
|
|
130
139
|
rack-protection (>= 1.5.0)
|
|
131
140
|
redis (~> 3.2, >= 3.2.1)
|
|
141
|
+
slop (3.6.0)
|
|
132
142
|
sprockets (3.7.1)
|
|
133
143
|
concurrent-ruby (~> 1.0)
|
|
134
144
|
rack (> 1, < 3)
|
|
@@ -152,6 +162,8 @@ DEPENDENCIES
|
|
|
152
162
|
activerecord-multi-tenant!
|
|
153
163
|
appraisal
|
|
154
164
|
pg
|
|
165
|
+
pry
|
|
166
|
+
pry-byebug
|
|
155
167
|
rake
|
|
156
168
|
rspec (>= 3.0)
|
|
157
169
|
rspec-rails
|
|
@@ -159,4 +171,4 @@ DEPENDENCIES
|
|
|
159
171
|
thor
|
|
160
172
|
|
|
161
173
|
BUNDLED WITH
|
|
162
|
-
1.15.
|
|
174
|
+
1.15.3
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
activerecord-multi-tenant (0.
|
|
4
|
+
activerecord-multi-tenant (0.8.0)
|
|
5
5
|
rails (>= 3.1)
|
|
6
6
|
request_store (>= 1.0.5)
|
|
7
7
|
|
|
@@ -38,6 +38,8 @@ GEM
|
|
|
38
38
|
thor (>= 0.14.0)
|
|
39
39
|
arel (4.0.2)
|
|
40
40
|
builder (3.1.4)
|
|
41
|
+
byebug (9.0.6)
|
|
42
|
+
coderay (1.1.1)
|
|
41
43
|
concurrent-ruby (1.0.5)
|
|
42
44
|
connection_pool (2.2.1)
|
|
43
45
|
diff-lcs (1.3)
|
|
@@ -45,12 +47,20 @@ GEM
|
|
|
45
47
|
i18n (0.8.1)
|
|
46
48
|
mail (2.6.4)
|
|
47
49
|
mime-types (>= 1.16, < 4)
|
|
50
|
+
method_source (0.8.2)
|
|
48
51
|
mime-types (3.1)
|
|
49
52
|
mime-types-data (~> 3.2015)
|
|
50
53
|
mime-types-data (3.2016.0521)
|
|
51
54
|
minitest (4.7.5)
|
|
52
55
|
multi_json (1.12.1)
|
|
53
56
|
pg (0.20.0)
|
|
57
|
+
pry (0.10.4)
|
|
58
|
+
coderay (~> 1.1.0)
|
|
59
|
+
method_source (~> 0.8.1)
|
|
60
|
+
slop (~> 3.4)
|
|
61
|
+
pry-byebug (3.4.2)
|
|
62
|
+
byebug (~> 9.0)
|
|
63
|
+
pry (~> 0.10)
|
|
54
64
|
rack (1.5.5)
|
|
55
65
|
rack-protection (2.0.0)
|
|
56
66
|
rack
|
|
@@ -98,6 +108,7 @@ GEM
|
|
|
98
108
|
connection_pool (~> 2.2, >= 2.2.0)
|
|
99
109
|
rack-protection (>= 1.5.0)
|
|
100
110
|
redis (~> 3.3, >= 3.3.3)
|
|
111
|
+
slop (3.6.0)
|
|
101
112
|
sprockets (3.7.1)
|
|
102
113
|
concurrent-ruby (~> 1.0)
|
|
103
114
|
rack (> 1, < 3)
|
|
@@ -116,6 +127,8 @@ DEPENDENCIES
|
|
|
116
127
|
activerecord-multi-tenant!
|
|
117
128
|
appraisal
|
|
118
129
|
pg
|
|
130
|
+
pry
|
|
131
|
+
pry-byebug
|
|
119
132
|
rails (= 4.0.13)
|
|
120
133
|
rake
|
|
121
134
|
rspec (>= 3.0)
|
|
@@ -124,4 +137,4 @@ DEPENDENCIES
|
|
|
124
137
|
thor
|
|
125
138
|
|
|
126
139
|
BUNDLED WITH
|
|
127
|
-
1.15.
|
|
140
|
+
1.15.3
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
activerecord-multi-tenant (0.
|
|
4
|
+
activerecord-multi-tenant (0.8.0)
|
|
5
5
|
rails (>= 3.1)
|
|
6
6
|
request_store (>= 1.0.5)
|
|
7
7
|
|
|
@@ -40,6 +40,8 @@ GEM
|
|
|
40
40
|
thor (>= 0.14.0)
|
|
41
41
|
arel (5.0.1.20140414130214)
|
|
42
42
|
builder (3.2.3)
|
|
43
|
+
byebug (9.0.6)
|
|
44
|
+
coderay (1.1.1)
|
|
43
45
|
concurrent-ruby (1.0.5)
|
|
44
46
|
connection_pool (2.2.1)
|
|
45
47
|
diff-lcs (1.3)
|
|
@@ -48,11 +50,19 @@ GEM
|
|
|
48
50
|
json (1.8.6)
|
|
49
51
|
mail (2.6.4)
|
|
50
52
|
mime-types (>= 1.16, < 4)
|
|
53
|
+
method_source (0.8.2)
|
|
51
54
|
mime-types (3.1)
|
|
52
55
|
mime-types-data (~> 3.2015)
|
|
53
56
|
mime-types-data (3.2016.0521)
|
|
54
57
|
minitest (5.10.1)
|
|
55
58
|
pg (0.20.0)
|
|
59
|
+
pry (0.10.4)
|
|
60
|
+
coderay (~> 1.1.0)
|
|
61
|
+
method_source (~> 0.8.1)
|
|
62
|
+
slop (~> 3.4)
|
|
63
|
+
pry-byebug (3.4.2)
|
|
64
|
+
byebug (~> 9.0)
|
|
65
|
+
pry (~> 0.10)
|
|
56
66
|
rack (1.5.5)
|
|
57
67
|
rack-protection (2.0.0)
|
|
58
68
|
rack
|
|
@@ -102,6 +112,7 @@ GEM
|
|
|
102
112
|
connection_pool (~> 2.2, >= 2.2.0)
|
|
103
113
|
rack-protection (>= 1.5.0)
|
|
104
114
|
redis (~> 3.3, >= 3.3.3)
|
|
115
|
+
slop (3.6.0)
|
|
105
116
|
sprockets (3.7.1)
|
|
106
117
|
concurrent-ruby (~> 1.0)
|
|
107
118
|
rack (> 1, < 3)
|
|
@@ -121,6 +132,8 @@ DEPENDENCIES
|
|
|
121
132
|
activerecord-multi-tenant!
|
|
122
133
|
appraisal
|
|
123
134
|
pg
|
|
135
|
+
pry
|
|
136
|
+
pry-byebug
|
|
124
137
|
rails (= 4.1.16)
|
|
125
138
|
rake
|
|
126
139
|
rspec (>= 3.0)
|
|
@@ -129,4 +142,4 @@ DEPENDENCIES
|
|
|
129
142
|
thor
|
|
130
143
|
|
|
131
144
|
BUNDLED WITH
|
|
132
|
-
1.15.
|
|
145
|
+
1.15.3
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
activerecord-multi-tenant (0.
|
|
4
|
+
activerecord-multi-tenant (0.8.0)
|
|
5
5
|
rails (>= 3.1)
|
|
6
6
|
request_store (>= 1.0.5)
|
|
7
7
|
|
|
@@ -48,6 +48,8 @@ GEM
|
|
|
48
48
|
thor (>= 0.14.0)
|
|
49
49
|
arel (6.0.4)
|
|
50
50
|
builder (3.2.3)
|
|
51
|
+
byebug (9.0.6)
|
|
52
|
+
coderay (1.1.1)
|
|
51
53
|
concurrent-ruby (1.0.5)
|
|
52
54
|
connection_pool (2.2.1)
|
|
53
55
|
diff-lcs (1.3)
|
|
@@ -59,6 +61,7 @@ GEM
|
|
|
59
61
|
nokogiri (>= 1.5.9)
|
|
60
62
|
mail (2.6.4)
|
|
61
63
|
mime-types (>= 1.16, < 4)
|
|
64
|
+
method_source (0.8.2)
|
|
62
65
|
mime-types (3.1)
|
|
63
66
|
mime-types-data (~> 3.2015)
|
|
64
67
|
mime-types-data (3.2016.0521)
|
|
@@ -67,6 +70,13 @@ GEM
|
|
|
67
70
|
nokogiri (1.7.1)
|
|
68
71
|
mini_portile2 (~> 2.1.0)
|
|
69
72
|
pg (0.20.0)
|
|
73
|
+
pry (0.10.4)
|
|
74
|
+
coderay (~> 1.1.0)
|
|
75
|
+
method_source (~> 0.8.1)
|
|
76
|
+
slop (~> 3.4)
|
|
77
|
+
pry-byebug (3.4.2)
|
|
78
|
+
byebug (~> 9.0)
|
|
79
|
+
pry (~> 0.10)
|
|
70
80
|
rack (1.6.5)
|
|
71
81
|
rack-protection (1.5.3)
|
|
72
82
|
rack
|
|
@@ -125,6 +135,7 @@ GEM
|
|
|
125
135
|
connection_pool (~> 2.2, >= 2.2.0)
|
|
126
136
|
rack-protection (>= 1.5.0)
|
|
127
137
|
redis (~> 3.2, >= 3.2.1)
|
|
138
|
+
slop (3.6.0)
|
|
128
139
|
sprockets (3.7.1)
|
|
129
140
|
concurrent-ruby (~> 1.0)
|
|
130
141
|
rack (> 1, < 3)
|
|
@@ -144,6 +155,8 @@ DEPENDENCIES
|
|
|
144
155
|
activerecord-multi-tenant!
|
|
145
156
|
appraisal
|
|
146
157
|
pg
|
|
158
|
+
pry
|
|
159
|
+
pry-byebug
|
|
147
160
|
rails (= 4.2.8)
|
|
148
161
|
rake
|
|
149
162
|
rspec (>= 3.0)
|
|
@@ -152,4 +165,4 @@ DEPENDENCIES
|
|
|
152
165
|
thor
|
|
153
166
|
|
|
154
167
|
BUNDLED WITH
|
|
155
|
-
1.15.
|
|
168
|
+
1.15.3
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
activerecord-multi-tenant (0.
|
|
4
|
+
activerecord-multi-tenant (0.8.0)
|
|
5
5
|
rails (>= 3.1)
|
|
6
6
|
request_store (>= 1.0.5)
|
|
7
7
|
|
|
@@ -51,6 +51,8 @@ GEM
|
|
|
51
51
|
thor (>= 0.14.0)
|
|
52
52
|
arel (7.1.4)
|
|
53
53
|
builder (3.2.3)
|
|
54
|
+
byebug (9.0.6)
|
|
55
|
+
coderay (1.1.1)
|
|
54
56
|
concurrent-ruby (1.0.5)
|
|
55
57
|
connection_pool (2.2.1)
|
|
56
58
|
diff-lcs (1.3)
|
|
@@ -72,6 +74,13 @@ GEM
|
|
|
72
74
|
nokogiri (1.7.1)
|
|
73
75
|
mini_portile2 (~> 2.1.0)
|
|
74
76
|
pg (0.20.0)
|
|
77
|
+
pry (0.10.4)
|
|
78
|
+
coderay (~> 1.1.0)
|
|
79
|
+
method_source (~> 0.8.1)
|
|
80
|
+
slop (~> 3.4)
|
|
81
|
+
pry-byebug (3.4.2)
|
|
82
|
+
byebug (~> 9.0)
|
|
83
|
+
pry (~> 0.10)
|
|
75
84
|
rack (2.0.1)
|
|
76
85
|
rack-protection (1.5.3)
|
|
77
86
|
rack
|
|
@@ -129,6 +138,7 @@ GEM
|
|
|
129
138
|
connection_pool (~> 2.2, >= 2.2.0)
|
|
130
139
|
rack-protection (>= 1.5.0)
|
|
131
140
|
redis (~> 3.2, >= 3.2.1)
|
|
141
|
+
slop (3.6.0)
|
|
132
142
|
sprockets (3.7.1)
|
|
133
143
|
concurrent-ruby (~> 1.0)
|
|
134
144
|
rack (> 1, < 3)
|
|
@@ -151,6 +161,8 @@ DEPENDENCIES
|
|
|
151
161
|
activerecord-multi-tenant!
|
|
152
162
|
appraisal
|
|
153
163
|
pg
|
|
164
|
+
pry
|
|
165
|
+
pry-byebug
|
|
154
166
|
rails (= 5.0.1)
|
|
155
167
|
rake
|
|
156
168
|
rspec (>= 3.0)
|
|
@@ -159,4 +171,4 @@ DEPENDENCIES
|
|
|
159
171
|
thor
|
|
160
172
|
|
|
161
173
|
BUNDLED WITH
|
|
162
|
-
1.15.
|
|
174
|
+
1.15.3
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
activerecord-multi-tenant (0.
|
|
4
|
+
activerecord-multi-tenant (0.8.0)
|
|
5
5
|
rails (>= 3.1)
|
|
6
6
|
request_store (>= 1.0.5)
|
|
7
7
|
|
|
@@ -51,6 +51,8 @@ GEM
|
|
|
51
51
|
thor (>= 0.14.0)
|
|
52
52
|
arel (8.0.0)
|
|
53
53
|
builder (3.2.3)
|
|
54
|
+
byebug (9.0.6)
|
|
55
|
+
coderay (1.1.1)
|
|
54
56
|
concurrent-ruby (1.0.5)
|
|
55
57
|
connection_pool (2.2.1)
|
|
56
58
|
diff-lcs (1.3)
|
|
@@ -72,6 +74,13 @@ GEM
|
|
|
72
74
|
nokogiri (1.7.1)
|
|
73
75
|
mini_portile2 (~> 2.1.0)
|
|
74
76
|
pg (0.20.0)
|
|
77
|
+
pry (0.10.4)
|
|
78
|
+
coderay (~> 1.1.0)
|
|
79
|
+
method_source (~> 0.8.1)
|
|
80
|
+
slop (~> 3.4)
|
|
81
|
+
pry-byebug (3.4.2)
|
|
82
|
+
byebug (~> 9.0)
|
|
83
|
+
pry (~> 0.10)
|
|
75
84
|
rack (2.0.1)
|
|
76
85
|
rack-protection (1.5.3)
|
|
77
86
|
rack
|
|
@@ -129,6 +138,7 @@ GEM
|
|
|
129
138
|
connection_pool (~> 2.2, >= 2.2.0)
|
|
130
139
|
rack-protection (>= 1.5.0)
|
|
131
140
|
redis (~> 3.2, >= 3.2.1)
|
|
141
|
+
slop (3.6.0)
|
|
132
142
|
sprockets (3.7.1)
|
|
133
143
|
concurrent-ruby (~> 1.0)
|
|
134
144
|
rack (> 1, < 3)
|
|
@@ -151,6 +161,8 @@ DEPENDENCIES
|
|
|
151
161
|
activerecord-multi-tenant!
|
|
152
162
|
appraisal
|
|
153
163
|
pg
|
|
164
|
+
pry
|
|
165
|
+
pry-byebug
|
|
154
166
|
rails (= 5.1.0)
|
|
155
167
|
rake
|
|
156
168
|
rspec (>= 3.0)
|
|
@@ -159,4 +171,4 @@ DEPENDENCIES
|
|
|
159
171
|
thor
|
|
160
172
|
|
|
161
173
|
BUNDLED WITH
|
|
162
|
-
1.15.
|
|
174
|
+
1.15.3
|
|
@@ -1,60 +1,117 @@
|
|
|
1
1
|
require 'active_record'
|
|
2
2
|
|
|
3
3
|
module MultiTenant
|
|
4
|
+
class Table
|
|
5
|
+
attr_reader :arel_table
|
|
6
|
+
|
|
7
|
+
def initialize(arel_table)
|
|
8
|
+
@arel_table = arel_table
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def eql?(rhs)
|
|
12
|
+
self.class == rhs.class &&
|
|
13
|
+
equality_fields.eql?(rhs.equality_fields)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def hash
|
|
17
|
+
equality_fields.hash
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
protected
|
|
21
|
+
|
|
22
|
+
def equality_fields
|
|
23
|
+
[arel_table.name, arel_table.table_alias]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class Context
|
|
28
|
+
attr_reader :arel_node, :known_relations, :handled_relations
|
|
29
|
+
|
|
30
|
+
def initialize(arel_node)
|
|
31
|
+
@arel_node = arel_node
|
|
32
|
+
@known_relations = []
|
|
33
|
+
@handled_relations = []
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def discover_relations
|
|
37
|
+
old_discovering = @discovering
|
|
38
|
+
@discovering = true
|
|
39
|
+
yield
|
|
40
|
+
@discovering = old_discovering
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def visited_relation(relation)
|
|
44
|
+
return unless @discovering
|
|
45
|
+
@known_relations << Table.new(relation)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def visited_handled_relation(relation)
|
|
49
|
+
@handled_relations << Table.new(relation)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def unhandled_relations
|
|
53
|
+
known_relations.uniq - handled_relations
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
4
57
|
class ArelTenantVisitor < Arel::Visitors::DepthFirst
|
|
5
58
|
def initialize(arel)
|
|
6
59
|
super(Proc.new {})
|
|
7
|
-
@tenant_relations = {}
|
|
8
|
-
@existing_tenant_relations = {}
|
|
9
|
-
@outer_joins_by_table_name = {}
|
|
10
60
|
@statement_node_id = nil
|
|
11
61
|
|
|
62
|
+
@contexts = []
|
|
63
|
+
@current_context = nil
|
|
12
64
|
accept(arel.ast)
|
|
13
65
|
end
|
|
14
66
|
|
|
15
|
-
|
|
16
|
-
|
|
67
|
+
attr_reader :contexts
|
|
68
|
+
|
|
69
|
+
def visit_Arel_Attributes_Attribute(*args)
|
|
70
|
+
return if @current_context.nil?
|
|
71
|
+
super(*args)
|
|
17
72
|
end
|
|
18
73
|
|
|
19
|
-
def
|
|
20
|
-
|
|
74
|
+
def visit_Arel_Nodes_Equality(o, *args)
|
|
75
|
+
if o.left.is_a?(Arel::Attributes::Attribute)
|
|
76
|
+
table_name = o.left.relation.table_name
|
|
77
|
+
model = MultiTenant.multi_tenant_model_for_table(table_name)
|
|
78
|
+
@current_context.visited_handled_relation(o.left.relation) if model.present? && o.left.name == model.partition_key
|
|
79
|
+
end
|
|
80
|
+
super(o, *args)
|
|
21
81
|
end
|
|
22
82
|
|
|
23
|
-
def
|
|
24
|
-
@
|
|
83
|
+
def visit_MultiTenant_TenantEnforcementClause(o, *)
|
|
84
|
+
@current_context.visited_handled_relation(o.tenant_attribute.relation)
|
|
25
85
|
end
|
|
26
86
|
|
|
27
87
|
def visit_Arel_Table(o, _collector = nil)
|
|
28
|
-
@
|
|
29
|
-
@tenant_relations[@statement_node_id] << o if tenant_relation?(o.table_name)
|
|
88
|
+
@current_context.visited_relation(o) if tenant_relation?(o.table_name)
|
|
30
89
|
end
|
|
31
90
|
alias :visit_Arel_Nodes_TableAlias :visit_Arel_Table
|
|
32
91
|
|
|
33
|
-
def
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@existing_tenant_relations[@statement_node_id] ||= []
|
|
47
|
-
@existing_tenant_relations[@statement_node_id] << o.left.relation if model.present? && o.left.name == model.partition_key
|
|
92
|
+
def visit_Arel_Nodes_SelectCore(o, *args)
|
|
93
|
+
nest_context(o) do
|
|
94
|
+
@current_context.discover_relations do
|
|
95
|
+
visit o.source
|
|
96
|
+
end
|
|
97
|
+
visit o.wheres
|
|
98
|
+
visit o.groups
|
|
99
|
+
visit o.windows
|
|
100
|
+
if defined?(o.having)
|
|
101
|
+
visit o.having
|
|
102
|
+
else
|
|
103
|
+
visit o.havings
|
|
104
|
+
end
|
|
48
105
|
end
|
|
49
106
|
end
|
|
50
107
|
|
|
51
108
|
def visit_Arel_Nodes_OuterJoin(o, collector = nil)
|
|
52
|
-
|
|
53
|
-
@
|
|
54
|
-
|
|
109
|
+
nest_context(o) do
|
|
110
|
+
@current_context.discover_relations do
|
|
111
|
+
visit o.left
|
|
112
|
+
visit o.right
|
|
113
|
+
end
|
|
55
114
|
end
|
|
56
|
-
visit o.left
|
|
57
|
-
visit o.right
|
|
58
115
|
end
|
|
59
116
|
alias :visit_Arel_Nodes_FullOuterJoin :visit_Arel_Nodes_OuterJoin
|
|
60
117
|
alias :visit_Arel_Nodes_RightOuterJoin :visit_Arel_Nodes_OuterJoin
|
|
@@ -64,9 +121,73 @@ module MultiTenant
|
|
|
64
121
|
def tenant_relation?(table_name)
|
|
65
122
|
MultiTenant.multi_tenant_model_for_table(table_name).present?
|
|
66
123
|
end
|
|
124
|
+
|
|
125
|
+
DISPATCH = Hash.new do |hash, klass|
|
|
126
|
+
hash[klass] = "visit_#{(klass.name || '').gsub('::', '_')}"
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def dispatch
|
|
130
|
+
DISPATCH
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def get_dispatch_cache
|
|
134
|
+
dispatch
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def nest_context(o)
|
|
138
|
+
old_context = @current_context
|
|
139
|
+
@current_context = Context.new(o)
|
|
140
|
+
@contexts << @current_context
|
|
141
|
+
|
|
142
|
+
yield
|
|
143
|
+
|
|
144
|
+
@current_context = old_context
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
class TenantEnforcementClause < Arel::Nodes::Node
|
|
149
|
+
attr_reader :tenant_attribute
|
|
150
|
+
def initialize(tenant_attribute)
|
|
151
|
+
@tenant_attribute = tenant_attribute
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def to_s; to_sql; end
|
|
155
|
+
def to_str; to_sql; end
|
|
156
|
+
|
|
157
|
+
def to_sql(*)
|
|
158
|
+
if MultiTenant.current_tenant_id
|
|
159
|
+
tenant_arel.to_sql
|
|
160
|
+
else
|
|
161
|
+
'1=1'
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
private
|
|
166
|
+
|
|
167
|
+
def tenant_arel
|
|
168
|
+
if defined?(Arel::Nodes::Quoted)
|
|
169
|
+
@tenant_attribute.eq(Arel::Nodes::Quoted.new(MultiTenant.current_tenant_id))
|
|
170
|
+
else
|
|
171
|
+
@tenant_attribute.eq(MultiTenant.current_tenant_id)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
module TenantValueVisitor
|
|
177
|
+
if ActiveRecord::VERSION::MAJOR > 4 || (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 2)
|
|
178
|
+
def visit_MultiTenant_TenantEnforcementClause(o, collector)
|
|
179
|
+
collector << o
|
|
180
|
+
end
|
|
181
|
+
else
|
|
182
|
+
def visit_MultiTenant_TenantEnforcementClause(o, a = nil)
|
|
183
|
+
o
|
|
184
|
+
end
|
|
185
|
+
end
|
|
67
186
|
end
|
|
68
187
|
end
|
|
69
188
|
|
|
189
|
+
Arel::Visitors::ToSql.include(MultiTenant::TenantValueVisitor)
|
|
190
|
+
|
|
70
191
|
require 'active_record/relation'
|
|
71
192
|
module ActiveRecord
|
|
72
193
|
module QueryMethods
|
|
@@ -76,36 +197,23 @@ module ActiveRecord
|
|
|
76
197
|
|
|
77
198
|
if MultiTenant.current_tenant_id && !MultiTenant.with_write_only_mode_enabled?
|
|
78
199
|
visitor = MultiTenant::ArelTenantVisitor.new(arel)
|
|
79
|
-
visitor.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
known_model = MultiTenant.multi_tenant_model_for_table(tenant_relation.table_name)
|
|
92
|
-
tenant_relation[known_model.partition_key]
|
|
93
|
-
else
|
|
94
|
-
MultiTenant.current_tenant_id
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
known_relations << relation
|
|
98
|
-
|
|
99
|
-
outer_join = outer_joins_by_table_name[relation.name]
|
|
100
|
-
if outer_join
|
|
101
|
-
outer_join.right.expr = Arel::Nodes::And.new([outer_join.right.expr, relation[model.partition_key].eq(tenant_value)])
|
|
102
|
-
else
|
|
103
|
-
ctx = arel.ast.cores.last
|
|
104
|
-
if ctx.wheres.size == 1
|
|
105
|
-
ctx.wheres = [Arel::Nodes::And.new([ctx.wheres.first, relation[model.partition_key].eq(tenant_value)])]
|
|
200
|
+
visitor.contexts.each do |context|
|
|
201
|
+
node = context.arel_node
|
|
202
|
+
context.unhandled_relations.each do |relation|
|
|
203
|
+
model = MultiTenant.multi_tenant_model_for_table(relation.arel_table.table_name)
|
|
204
|
+
enforcement_clause = MultiTenant::TenantEnforcementClause.new(relation.arel_table[model.partition_key])
|
|
205
|
+
|
|
206
|
+
case node
|
|
207
|
+
when Arel::Nodes::Join #Arel::Nodes::OuterJoin, Arel::Nodes::RightOuterJoin, Arel::Nodes::FullOuterJoin
|
|
208
|
+
node.right.expr = node.right.expr.and(enforcement_clause)
|
|
209
|
+
when Arel::Nodes::SelectCore
|
|
210
|
+
if node.wheres.empty?
|
|
211
|
+
node.wheres = [enforcement_clause]
|
|
106
212
|
else
|
|
107
|
-
|
|
213
|
+
node.wheres[0] = enforcement_clause.and(node.wheres[0])
|
|
108
214
|
end
|
|
215
|
+
else
|
|
216
|
+
raise "UnknownContext"
|
|
109
217
|
end
|
|
110
218
|
end
|
|
111
219
|
end
|
|
@@ -9,11 +9,7 @@ describe "Controller Extensions", type: :controller do
|
|
|
9
9
|
include Rails.application.routes.url_helpers
|
|
10
10
|
set_current_tenant_through_filter
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
before_filter :your_method_that_finds_the_current_tenant
|
|
14
|
-
else
|
|
15
|
-
before_action :your_method_that_finds_the_current_tenant
|
|
16
|
-
end
|
|
12
|
+
before_action :your_method_that_finds_the_current_tenant
|
|
17
13
|
|
|
18
14
|
def your_method_that_finds_the_current_tenant
|
|
19
15
|
current_account = Account.new
|
|
@@ -287,8 +287,71 @@ describe MultiTenant do
|
|
|
287
287
|
end
|
|
288
288
|
end
|
|
289
289
|
|
|
290
|
-
|
|
291
|
-
|
|
290
|
+
it 'does not cache tenancy in associations' do
|
|
291
|
+
account1 = Account.create! name: 'test1'
|
|
292
|
+
account2 = Account.create! name: 'test2'
|
|
293
|
+
|
|
294
|
+
MultiTenant.with(account1) do
|
|
295
|
+
project1 = Project.create! name: 'something1'
|
|
296
|
+
task1 = Task.create! name: 'task1', project: project1
|
|
297
|
+
subtask1 = SubTask.create! task: task1
|
|
298
|
+
|
|
299
|
+
expect(subtask1.project).to be_present
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
MultiTenant.with(account2) do
|
|
303
|
+
project2 = Project.create! name: 'something2'
|
|
304
|
+
task2 = Task.create! name: 'task2', project: project2
|
|
305
|
+
subtask2 = SubTask.create! task: task2
|
|
306
|
+
|
|
307
|
+
expect(subtask2.project).to be_present
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
it "applies the team_id conditions in the where clause" do
|
|
312
|
+
expected_sql = <<-sql
|
|
313
|
+
SELECT "sub_tasks".* FROM "sub_tasks" INNER JOIN "tasks" ON "sub_tasks"."task_id" = "tasks"."id" WHERE "tasks"."account_id" = 1 AND "sub_tasks"."account_id" = 1 AND "tasks"."project_id" = 1
|
|
314
|
+
sql
|
|
315
|
+
account1 = Account.create! name: 'Account 1'
|
|
316
|
+
|
|
317
|
+
MultiTenant.with(account1) do
|
|
318
|
+
project1 = Project.create! name: 'Project 1'
|
|
319
|
+
task1 = Task.create! name: 'Task 1', project: project1
|
|
320
|
+
subtask1 = SubTask.create! task: task1
|
|
321
|
+
|
|
322
|
+
expect(project1.sub_tasks.to_sql).to eq(expected_sql.strip)
|
|
323
|
+
expect(project1.sub_tasks).to include(subtask1)
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
# Versions earlier than 4.2 pass an arel object to find_by_sql(...) and it would make
|
|
328
|
+
# this test unnecesssarily complicated to support that
|
|
329
|
+
if ActiveRecord::VERSION::MAJOR > 4 || (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 2)
|
|
330
|
+
it "only applies clauses when a tenant is set" do
|
|
331
|
+
account = Account.create! name: 'Account 1'
|
|
332
|
+
project = Project.create! name: 'Project 1', account: account
|
|
333
|
+
project2 = Project.create! name: 'Project 2', account: Account.create!(name: 'Account2')
|
|
334
|
+
|
|
335
|
+
MultiTenant.with(account) do
|
|
336
|
+
expected_sql = <<-sql.strip
|
|
337
|
+
SELECT "projects".* FROM "projects" WHERE "projects"."account_id" = #{account.id} AND "projects"."id" = #{project.id} LIMIT 1
|
|
338
|
+
sql
|
|
339
|
+
expect(Project).to receive(:find_by_sql).with(expected_sql, any_args).and_call_original
|
|
340
|
+
expect(Project.find(project.id)).to eq(project)
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
MultiTenant.with(nil) do
|
|
344
|
+
expected_sql = <<-sql.strip
|
|
345
|
+
SELECT "projects".* FROM "projects" WHERE 1=1 AND "projects"."id" = #{project2.id} LIMIT 1
|
|
346
|
+
sql
|
|
347
|
+
expect(Project).to receive(:find_by_sql).with(expected_sql, any_args).and_call_original
|
|
348
|
+
expect(Project.find(project2.id)).to eq(project2)
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
# Versions earlier than 4.1 have a different behaviour regarding unsaved associations
|
|
354
|
+
if ActiveRecord::VERSION::MAJOR > 4 || (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 1)
|
|
292
355
|
describe 'with unsaved association' do
|
|
293
356
|
before do
|
|
294
357
|
@account = Account.create!(name: 'reflection tenant')
|
|
@@ -8,4 +8,12 @@ describe MultiTenant, 'Record finding' do
|
|
|
8
8
|
expect(Project.find(project.id)).to be_present
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
|
+
|
|
12
|
+
it 'supports UUIDs' do
|
|
13
|
+
organization = Organization.create! name: 'test'
|
|
14
|
+
uuid_record = organization.uuid_records.create! description: 'something'
|
|
15
|
+
MultiTenant.with(organization) do
|
|
16
|
+
expect(UuidRecord.find(uuid_record.id)).to be_present
|
|
17
|
+
end
|
|
18
|
+
end
|
|
11
19
|
end
|
data/spec/schema.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Resets the database, except when we are only running a specific spec
|
|
2
2
|
ARGV.grep(/\w+_spec\.rb/).empty? && ActiveRecord::Schema.define(version: 1) do
|
|
3
|
+
enable_extension_on_all_nodes 'uuid-ossp'
|
|
4
|
+
enable_extension_on_all_nodes 'pgcrypto'
|
|
5
|
+
|
|
3
6
|
create_table :accounts, force: true do |t|
|
|
4
7
|
t.column :name, :string
|
|
5
8
|
t.column :subdomain, :string
|
|
@@ -66,6 +69,15 @@ ARGV.grep(/\w+_spec\.rb/).empty? && ActiveRecord::Schema.define(version: 1) do
|
|
|
66
69
|
t.column :name, :string
|
|
67
70
|
end
|
|
68
71
|
|
|
72
|
+
create_table :organizations, force: true, id: :uuid do |t|
|
|
73
|
+
t.column :name, :string
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
create_table :uuid_records, force: true, partition_key: :organization_id do |t|
|
|
77
|
+
t.column :organization_id, :uuid
|
|
78
|
+
t.column :description, :string
|
|
79
|
+
end
|
|
80
|
+
|
|
69
81
|
create_distributed_table :accounts, :id
|
|
70
82
|
create_distributed_table :projects, :account_id
|
|
71
83
|
create_distributed_table :managers, :account_id
|
|
@@ -76,6 +88,7 @@ ARGV.grep(/\w+_spec\.rb/).empty? && ActiveRecord::Schema.define(version: 1) do
|
|
|
76
88
|
create_distributed_table :comments, :account_id
|
|
77
89
|
create_distributed_table :partition_key_not_model_tasks, :non_model_id
|
|
78
90
|
create_distributed_table :subclass_tasks, :non_model_id
|
|
91
|
+
create_distributed_table :uuid_records, :organization_id
|
|
79
92
|
end
|
|
80
93
|
|
|
81
94
|
class Account < ActiveRecord::Base
|
|
@@ -90,11 +103,7 @@ class Project < ActiveRecord::Base
|
|
|
90
103
|
has_many :tasks
|
|
91
104
|
has_many :sub_tasks, through: :tasks
|
|
92
105
|
|
|
93
|
-
|
|
94
|
-
validates_uniqueness_of :name, scope: [:account_id]
|
|
95
|
-
else
|
|
96
|
-
validates_uniqueness_of :name, scope: [:account]
|
|
97
|
-
end
|
|
106
|
+
validates_uniqueness_of :name, scope: [:account]
|
|
98
107
|
end
|
|
99
108
|
|
|
100
109
|
class Manager < ActiveRecord::Base
|
|
@@ -107,8 +116,6 @@ class Task < ActiveRecord::Base
|
|
|
107
116
|
belongs_to :project
|
|
108
117
|
has_many :sub_tasks
|
|
109
118
|
|
|
110
|
-
default_scope -> { where(completed: nil).order('name') }
|
|
111
|
-
|
|
112
119
|
validates_uniqueness_of :name
|
|
113
120
|
end
|
|
114
121
|
|
|
@@ -133,11 +140,7 @@ end
|
|
|
133
140
|
class CustomPartitionKeyTask < ActiveRecord::Base
|
|
134
141
|
multi_tenant :account, partition_key: 'accountID'
|
|
135
142
|
|
|
136
|
-
|
|
137
|
-
validates_uniqueness_of :name, scope: [:accountID]
|
|
138
|
-
else
|
|
139
|
-
validates_uniqueness_of :name, scope: [:account]
|
|
140
|
-
end
|
|
143
|
+
validates_uniqueness_of :name, scope: [:account]
|
|
141
144
|
end
|
|
142
145
|
|
|
143
146
|
class PartitionKeyNotModelTask < ActiveRecord::Base
|
|
@@ -160,3 +163,11 @@ class Comment < ActiveRecord::Base
|
|
|
160
163
|
belongs_to :task, -> { where(comments: { commentable_type: 'Task' }) }, foreign_key: 'commentable_id'
|
|
161
164
|
end
|
|
162
165
|
end
|
|
166
|
+
|
|
167
|
+
class Organization < ActiveRecord::Base
|
|
168
|
+
has_many :uuid_records
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
class UuidRecord < ActiveRecord::Base
|
|
172
|
+
multi_tenant :organization
|
|
173
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -7,6 +7,9 @@ require 'rspec/rails'
|
|
|
7
7
|
|
|
8
8
|
require 'activerecord-multi-tenant'
|
|
9
9
|
|
|
10
|
+
require 'bundler'
|
|
11
|
+
Bundler.require(:default, :development)
|
|
12
|
+
|
|
10
13
|
dbconfig = YAML::load(IO.read(File.join(File.dirname(__FILE__), 'database.yml')))
|
|
11
14
|
ActiveRecord::Base.logger = Logger.new(File.join(File.dirname(__FILE__), "debug.log"))
|
|
12
15
|
ActiveRecord::Base.establish_connection(dbconfig['test'])
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerecord-multi-tenant
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Citus Data
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-08-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: request_store
|
|
@@ -122,6 +122,34 @@ dependencies:
|
|
|
122
122
|
- - ">="
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
124
|
version: '0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: pry
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: pry-byebug
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - ">="
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0'
|
|
125
153
|
description: ''
|
|
126
154
|
email: engage@citusdata.com
|
|
127
155
|
executables: []
|
|
@@ -140,8 +168,6 @@ files:
|
|
|
140
168
|
- docker-compose.yml
|
|
141
169
|
- gemfiles/active_record_5.1.gemfile
|
|
142
170
|
- gemfiles/active_record_5.1.gemfile.lock
|
|
143
|
-
- gemfiles/rails_3.2.gemfile
|
|
144
|
-
- gemfiles/rails_3.2.gemfile.lock
|
|
145
171
|
- gemfiles/rails_4.0.gemfile
|
|
146
172
|
- gemfiles/rails_4.0.gemfile.lock
|
|
147
173
|
- gemfiles/rails_4.1.gemfile
|
data/gemfiles/rails_3.2.gemfile
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: ..
|
|
3
|
-
specs:
|
|
4
|
-
activerecord-multi-tenant (0.7.0)
|
|
5
|
-
rails (>= 3.1)
|
|
6
|
-
request_store (>= 1.0.5)
|
|
7
|
-
|
|
8
|
-
GEM
|
|
9
|
-
remote: https://rubygems.org/
|
|
10
|
-
specs:
|
|
11
|
-
actionmailer (3.2.22.5)
|
|
12
|
-
actionpack (= 3.2.22.5)
|
|
13
|
-
mail (~> 2.5.4)
|
|
14
|
-
actionpack (3.2.22.5)
|
|
15
|
-
activemodel (= 3.2.22.5)
|
|
16
|
-
activesupport (= 3.2.22.5)
|
|
17
|
-
builder (~> 3.0.0)
|
|
18
|
-
erubis (~> 2.7.0)
|
|
19
|
-
journey (~> 1.0.4)
|
|
20
|
-
rack (~> 1.4.5)
|
|
21
|
-
rack-cache (~> 1.2)
|
|
22
|
-
rack-test (~> 0.6.1)
|
|
23
|
-
sprockets (~> 2.2.1)
|
|
24
|
-
activemodel (3.2.22.5)
|
|
25
|
-
activesupport (= 3.2.22.5)
|
|
26
|
-
builder (~> 3.0.0)
|
|
27
|
-
activerecord (3.2.22.5)
|
|
28
|
-
activemodel (= 3.2.22.5)
|
|
29
|
-
activesupport (= 3.2.22.5)
|
|
30
|
-
arel (~> 3.0.2)
|
|
31
|
-
tzinfo (~> 0.3.29)
|
|
32
|
-
activeresource (3.2.22.5)
|
|
33
|
-
activemodel (= 3.2.22.5)
|
|
34
|
-
activesupport (= 3.2.22.5)
|
|
35
|
-
activesupport (3.2.22.5)
|
|
36
|
-
i18n (~> 0.6, >= 0.6.4)
|
|
37
|
-
multi_json (~> 1.0)
|
|
38
|
-
appraisal (2.1.0)
|
|
39
|
-
bundler
|
|
40
|
-
rake
|
|
41
|
-
thor (>= 0.14.0)
|
|
42
|
-
arel (3.0.3)
|
|
43
|
-
builder (3.0.4)
|
|
44
|
-
concurrent-ruby (1.0.5)
|
|
45
|
-
connection_pool (2.2.1)
|
|
46
|
-
diff-lcs (1.3)
|
|
47
|
-
erubis (2.7.0)
|
|
48
|
-
hike (1.2.3)
|
|
49
|
-
i18n (0.8.1)
|
|
50
|
-
journey (1.0.4)
|
|
51
|
-
json (1.8.6)
|
|
52
|
-
mail (2.5.4)
|
|
53
|
-
mime-types (~> 1.16)
|
|
54
|
-
treetop (~> 1.4.8)
|
|
55
|
-
mime-types (1.25.1)
|
|
56
|
-
multi_json (1.12.1)
|
|
57
|
-
pg (0.20.0)
|
|
58
|
-
polyglot (0.3.5)
|
|
59
|
-
power_assert (1.0.1)
|
|
60
|
-
rack (1.4.7)
|
|
61
|
-
rack-cache (1.7.0)
|
|
62
|
-
rack (>= 0.4)
|
|
63
|
-
rack-protection (2.0.0)
|
|
64
|
-
rack
|
|
65
|
-
rack-ssl (1.3.4)
|
|
66
|
-
rack
|
|
67
|
-
rack-test (0.6.3)
|
|
68
|
-
rack (>= 1.0)
|
|
69
|
-
rails (3.2.22.5)
|
|
70
|
-
actionmailer (= 3.2.22.5)
|
|
71
|
-
actionpack (= 3.2.22.5)
|
|
72
|
-
activerecord (= 3.2.22.5)
|
|
73
|
-
activeresource (= 3.2.22.5)
|
|
74
|
-
activesupport (= 3.2.22.5)
|
|
75
|
-
bundler (~> 1.0)
|
|
76
|
-
railties (= 3.2.22.5)
|
|
77
|
-
railties (3.2.22.5)
|
|
78
|
-
actionpack (= 3.2.22.5)
|
|
79
|
-
activesupport (= 3.2.22.5)
|
|
80
|
-
rack-ssl (~> 1.3.2)
|
|
81
|
-
rake (>= 0.8.7)
|
|
82
|
-
rdoc (~> 3.4)
|
|
83
|
-
thor (>= 0.14.6, < 2.0)
|
|
84
|
-
rake (12.0.0)
|
|
85
|
-
rdoc (3.12.2)
|
|
86
|
-
json (~> 1.4)
|
|
87
|
-
redis (3.3.3)
|
|
88
|
-
request_store (1.3.2)
|
|
89
|
-
rspec (3.5.0)
|
|
90
|
-
rspec-core (~> 3.5.0)
|
|
91
|
-
rspec-expectations (~> 3.5.0)
|
|
92
|
-
rspec-mocks (~> 3.5.0)
|
|
93
|
-
rspec-core (3.5.4)
|
|
94
|
-
rspec-support (~> 3.5.0)
|
|
95
|
-
rspec-expectations (3.5.0)
|
|
96
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
97
|
-
rspec-support (~> 3.5.0)
|
|
98
|
-
rspec-mocks (3.5.0)
|
|
99
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
100
|
-
rspec-support (~> 3.5.0)
|
|
101
|
-
rspec-rails (3.5.2)
|
|
102
|
-
actionpack (>= 3.0)
|
|
103
|
-
activesupport (>= 3.0)
|
|
104
|
-
railties (>= 3.0)
|
|
105
|
-
rspec-core (~> 3.5.0)
|
|
106
|
-
rspec-expectations (~> 3.5.0)
|
|
107
|
-
rspec-mocks (~> 3.5.0)
|
|
108
|
-
rspec-support (~> 3.5.0)
|
|
109
|
-
rspec-support (3.5.0)
|
|
110
|
-
sidekiq (5.0.3)
|
|
111
|
-
concurrent-ruby (~> 1.0)
|
|
112
|
-
connection_pool (~> 2.2, >= 2.2.0)
|
|
113
|
-
rack-protection (>= 1.5.0)
|
|
114
|
-
redis (~> 3.3, >= 3.3.3)
|
|
115
|
-
sprockets (2.2.3)
|
|
116
|
-
hike (~> 1.2)
|
|
117
|
-
multi_json (~> 1.0)
|
|
118
|
-
rack (~> 1.0)
|
|
119
|
-
tilt (~> 1.1, != 1.3.0)
|
|
120
|
-
test-unit (3.2.3)
|
|
121
|
-
power_assert
|
|
122
|
-
thor (0.19.4)
|
|
123
|
-
tilt (1.4.1)
|
|
124
|
-
treetop (1.4.15)
|
|
125
|
-
polyglot
|
|
126
|
-
polyglot (>= 0.3.1)
|
|
127
|
-
tzinfo (0.3.53)
|
|
128
|
-
|
|
129
|
-
PLATFORMS
|
|
130
|
-
ruby
|
|
131
|
-
|
|
132
|
-
DEPENDENCIES
|
|
133
|
-
activerecord-multi-tenant!
|
|
134
|
-
appraisal
|
|
135
|
-
pg
|
|
136
|
-
rails (= 3.2.22.5)
|
|
137
|
-
rake
|
|
138
|
-
rspec (>= 3.0)
|
|
139
|
-
rspec-rails
|
|
140
|
-
sidekiq
|
|
141
|
-
test-unit (~> 3.0)
|
|
142
|
-
thor
|
|
143
|
-
|
|
144
|
-
BUNDLED WITH
|
|
145
|
-
1.15.1
|