activerecord-multi-tenant 1.0.4 → 1.2.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/CI.yml +63 -0
  3. data/.gitignore +2 -0
  4. data/.rspec +1 -0
  5. data/Appraisals +20 -47
  6. data/CHANGELOG.md +19 -0
  7. data/gemfiles/active_record_5.2.gemfile +3 -2
  8. data/gemfiles/active_record_6.0.gemfile +1 -1
  9. data/gemfiles/active_record_6.1.gemfile +8 -0
  10. data/gemfiles/active_record_7.0.gemfile +8 -0
  11. data/gemfiles/rails_5.2.gemfile +3 -2
  12. data/gemfiles/rails_6.0.gemfile +1 -1
  13. data/gemfiles/rails_6.1.gemfile +8 -0
  14. data/gemfiles/rails_7.0.gemfile +8 -0
  15. data/lib/activerecord-multi-tenant/arel_visitors_depth_first.rb +200 -0
  16. data/lib/activerecord-multi-tenant/controller_extensions.rb +2 -6
  17. data/lib/activerecord-multi-tenant/copy_from_client.rb +4 -4
  18. data/lib/activerecord-multi-tenant/migrations.rb +2 -2
  19. data/lib/activerecord-multi-tenant/model_extensions.rb +9 -9
  20. data/lib/activerecord-multi-tenant/multi_tenant.rb +1 -0
  21. data/lib/activerecord-multi-tenant/query_rewriter.rb +32 -75
  22. data/lib/activerecord-multi-tenant/sidekiq.rb +6 -1
  23. data/lib/activerecord-multi-tenant/version.rb +1 -1
  24. data/spec/activerecord-multi-tenant/controller_extensions_spec.rb +19 -24
  25. data/spec/activerecord-multi-tenant/model_extensions_spec.rb +58 -74
  26. data/spec/activerecord-multi-tenant/query_rewriter_spec.rb +25 -0
  27. data/spec/activerecord-multi-tenant/record_finding_spec.rb +36 -0
  28. data/spec/activerecord-multi-tenant/sidekiq_spec.rb +15 -4
  29. data/spec/schema.rb +28 -8
  30. data/spec/spec_helper.rb +1 -6
  31. metadata +13 -20
  32. data/.travis.yml +0 -57
  33. data/Gemfile.lock +0 -181
  34. data/gemfiles/active_record_5.1.gemfile +0 -15
  35. data/gemfiles/active_record_5.1.gemfile.lock +0 -180
  36. data/gemfiles/active_record_5.2.gemfile.lock +0 -188
  37. data/gemfiles/active_record_6.0.gemfile.lock +0 -198
  38. data/gemfiles/rails_4.2.gemfile +0 -16
  39. data/gemfiles/rails_4.2.gemfile.lock +0 -175
  40. data/gemfiles/rails_5.0.gemfile +0 -15
  41. data/gemfiles/rails_5.0.gemfile.lock +0 -180
  42. data/gemfiles/rails_5.1.gemfile +0 -15
  43. data/gemfiles/rails_5.1.gemfile.lock +0 -180
  44. data/gemfiles/rails_5.2.gemfile.lock +0 -188
  45. data/gemfiles/rails_6.0.gemfile.lock +0 -198
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4ba6283cdc0a3a6156de1ed6e48674650769dd98a563175e3f0f6ad145e948a1
4
- data.tar.gz: 4e60b1920f1b14a6707adf28fbd15135830a46a8085c07912fb5b190d7b677e9
3
+ metadata.gz: fa2e595cc76e33a877613504121106791680118da0a0c4957ff1190e75e99c3a
4
+ data.tar.gz: 8a232e3431462d5b8b3972f0825664c210cc51729b2e94d08c5529851365d7f8
5
5
  SHA512:
6
- metadata.gz: 84f4b35e8525f88193b08c719abce5c75d085bbfca9f517cc090d0a604cd435a23bf565c66e91c1cae30e45c06c92d7407829a0659a88843757baa54e0e6dd49
7
- data.tar.gz: 3495d94157cc8dc9528d55405eca44fd7c077fbd06bf841b915cc02e8d2940abff626d652802ff15b23f8a9192d8af76cbd038128be1a2a0369fba2f213458d0
6
+ metadata.gz: a2df2315ca041de29d2e82786a33904a9ac1dedd3f1ee4a2e470822cff977e9f4548ab0d33bd6eefec8055b9fc74ff8db2fdcf4c93cba4992aaaa681dcd1a695
7
+ data.tar.gz: 9da5eec93a1bcd33bff29ab1e0035022592802f512d27139608e92988a17365d3fe4cff0a73fc0f83e9513cea9dd2bf6233bb4deac9533320fb0884f7ef8b219
@@ -0,0 +1,63 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby:
16
+ - '2.5'
17
+ - '2.6'
18
+ - '2.7'
19
+ - '3.0'
20
+ - '3.1'
21
+ gemfile:
22
+ - rails_5.2
23
+ - rails_6.0
24
+ - rails_6.1
25
+ - rails_7.0
26
+ - active_record_5.2
27
+ - active_record_6.0
28
+ - active_record_6.1
29
+ - active_record_7.0
30
+ prepared_statements: [true, false]
31
+ exclude:
32
+ # activesupport-7.0.0 requires ruby version >= 2.7.0
33
+ - ruby: '2.5'
34
+ gemfile: 'rails_7.0'
35
+ - ruby: '2.5'
36
+ gemfile: 'active_record_7.0'
37
+ - ruby: '2.6'
38
+ gemfile: 'rails_7.0'
39
+ - ruby: '2.6'
40
+ gemfile: 'active_record_7.0'
41
+ # ruby >3 and activesupport 5.2 are not compatible
42
+ - ruby: '3.0'
43
+ gemfile: 'rails_5.2'
44
+ - ruby: '3.0'
45
+ gemfile: 'active_record_5.2'
46
+ - ruby: '3.1'
47
+ gemfile: 'rails_5.2'
48
+ - ruby: '3.1'
49
+ gemfile: 'active_record_5.2'
50
+ name: Ruby ${{ matrix.ruby }} / ${{ matrix.gemfile }} ${{ (matrix.prepared_statements && 'w/ prepared statements') || '' }}
51
+ env:
52
+ BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
53
+ PREPARED_STATEMENTS: ${{ matrix.prepared_statements && '1' }}
54
+ steps:
55
+ - uses: actions/checkout@v2
56
+ - run: |
57
+ docker-compose up -d
58
+ - uses: ruby/setup-ruby@v1
59
+ with:
60
+ ruby-version: ${{ matrix.ruby }}
61
+ bundler-cache: true
62
+ - run: |
63
+ bundle exec rake spec
data/.gitignore CHANGED
@@ -2,3 +2,5 @@ spec/debug.log
2
2
  pkg/
3
3
  *.rb#
4
4
  *.*~
5
+ Gemfile.lock
6
+ *.gemfile.lock
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --force-color
data/Appraisals CHANGED
@@ -1,61 +1,25 @@
1
- appraise 'rails-4.2' do
2
- gem 'rails', '~> 4.2.8'
3
- gem 'i18n', '~> 0.9.5'
4
- gem 'nokogiri', '~> 1.7.1'
5
- gem 'nio4r', '~> 2.3.1'
6
- gem 'sprockets', '~> 3.7.1'
7
- gem 'byebug', '~> 9.0.6'
8
- gem 'rake', '12.0.0'
9
- gem 'redis', '3.3.3'
10
- gem 'pg', '~> 0.15'
11
- end
12
-
13
- appraise 'rails-5.0' do
14
- gem 'rails', '~> 5.0.1'
15
- gem 'i18n', '~> 0.9.5'
16
- gem 'nokogiri', '~> 1.7.1'
17
- gem 'nio4r', '~> 2.3.1'
18
- gem 'sprockets', '~> 3.7.1'
19
- gem 'byebug', '~> 9.0.6'
20
- gem 'rake', '12.0.0'
21
- gem 'redis', '3.3.3'
22
- end
23
-
24
- appraise 'rails-5.1' do
25
- gem 'rails', '~> 5.1.0'
26
- gem 'i18n', '~> 0.9.5'
27
- gem 'nokogiri', '~> 1.7.1'
28
- gem 'nio4r', '~> 2.3.1'
29
- gem 'sprockets', '~> 3.7.1'
30
- gem 'byebug', '~> 9.0.6'
31
- gem 'rake', '12.0.0'
32
- gem 'redis', '3.3.3'
33
- end
34
-
35
1
  appraise 'rails-5.2' do
36
2
  gem 'rails', '~> 5.2.0'
37
3
  gem 'i18n', '~> 0.9.5'
38
4
  gem 'nokogiri', '~> 1.7.1'
39
5
  gem 'nio4r', '~> 2.3.1'
40
6
  gem 'sprockets', '~> 3.7.1'
41
- gem 'byebug', '~> 9.0.6'
7
+ gem 'byebug', '~> 11.0'
42
8
  gem 'rake', '12.0.0'
43
9
  gem 'redis', '3.3.3'
10
+ gem 'pry-byebug', '3.9.0'
44
11
  end
45
12
 
46
13
  appraise 'rails-6.0' do
47
- gem 'rails', '~> 6.0.0'
14
+ gem 'rails', '~> 6.0.3'
48
15
  end
49
16
 
50
- appraise 'active-record-5.1' do
51
- gem 'activerecord', '~> 5.1.0'
52
- gem 'i18n', '~> 0.9.5'
53
- gem 'nokogiri', '~> 1.7.1'
54
- gem 'nio4r', '~> 2.3.1'
55
- gem 'sprockets', '~> 3.7.1'
56
- gem 'byebug', '~> 9.0.6'
57
- gem 'rake', '12.0.0'
58
- gem 'redis', '3.3.3'
17
+ appraise 'rails-6.1' do
18
+ gem 'rails', '~> 6.1.0'
19
+ end
20
+
21
+ appraise 'rails-7.0' do
22
+ gem 'rails', '~> 7.0.0'
59
23
  end
60
24
 
61
25
  appraise 'active-record-5.2' do
@@ -64,11 +28,20 @@ appraise 'active-record-5.2' do
64
28
  gem 'nokogiri', '~> 1.7.1'
65
29
  gem 'nio4r', '~> 2.3.1'
66
30
  gem 'sprockets', '~> 3.7.1'
67
- gem 'byebug', '~> 9.0.6'
31
+ gem 'byebug', '~> 11.0'
68
32
  gem 'rake', '12.0.0'
69
33
  gem 'redis', '3.3.3'
34
+ gem 'pry-byebug', '3.9.0'
70
35
  end
71
36
 
72
37
  appraise 'active-record-6.0' do
73
- gem 'activerecord', '~> 6.0.0'
38
+ gem 'activerecord', '~> 6.0.3'
39
+ end
40
+
41
+ appraise 'active-record-6.1' do
42
+ gem 'activerecord', '~> 6.1.0'
43
+ end
44
+
45
+ appraise 'active-record-7.0' do
46
+ gem 'activerecord', '~> 7.0.0'
74
47
  end
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.2.0 2022-03-29
4
+
5
+ * Test Rails 7 & Ruby 3
6
+ * Fix regression in 1.1.1 involving deleted tenants [#123](https://github.com/citusdata/activerecord-multi-tenant/pull/123)
7
+ * Fix incorrect SQL generated when joining two models and one has a default scope [#132](https://github.com/citusdata/activerecord-multi-tenant/pull/132)
8
+ * Update for Rails 5+ removal of type_cast_for_database [#135](https://github.com/citusdata/activerecord-multi-tenant/pull/135)
9
+
10
+
11
+ ## 1.1.1 2021-01-15
12
+
13
+ * Add support for Rails 6.1 [#108](https://github.com/citusdata/activerecord-multi-tenant/pull/108)
14
+ * Fix statement cache for has_many through relations [#103](https://github.com/citusdata/activerecord-multi-tenant/pull/103)
15
+
16
+
17
+ ## 1.1.0 2020-08-06
18
+
19
+ * See commits for changes:
20
+ https://github.com/citusdata/activerecord-multi-tenant/commits/v1.1.0
21
+
3
22
 
4
23
  ## 1.0.4 2019-10-30
5
24
 
@@ -3,13 +3,14 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
- gem "activerecord", "~> 5.2.0"
6
+ gem "activerecord", "~> 5.2.0", "< 5.2.4" # FIXME
7
7
  gem "i18n", "~> 0.9.5"
8
8
  gem "nokogiri", "~> 1.7.1"
9
9
  gem "nio4r", "~> 2.3.1"
10
10
  gem "sprockets", "~> 3.7.1"
11
- gem "byebug", "~> 9.0.6"
11
+ gem "byebug", "~> 11.0"
12
12
  gem "rake", "12.0.0"
13
13
  gem "redis", "3.3.3"
14
+ gem "pry-byebug", "3.9.0"
14
15
 
15
16
  gemspec path: "../"
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
- gem "activerecord", "~> 6.0.0"
6
+ gem "activerecord", "~> 6.0.3"
7
7
 
8
8
  gemspec path: "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "activerecord", "~> 6.1.0"
7
+
8
+ gemspec path: "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "activerecord", "~> 7.0.0"
7
+
8
+ gemspec path: "../"
@@ -3,13 +3,14 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
- gem "rails", "~> 5.2.0"
6
+ gem "rails", "~> 5.2.0", "< 5.2.4" # FIXME
7
7
  gem "i18n", "~> 0.9.5"
8
8
  gem "nokogiri", "~> 1.7.1"
9
9
  gem "nio4r", "~> 2.3.1"
10
10
  gem "sprockets", "~> 3.7.1"
11
- gem "byebug", "~> 9.0.6"
11
+ gem "byebug", "~> 11.0"
12
12
  gem "rake", "12.0.0"
13
13
  gem "redis", "3.3.3"
14
+ gem "pry-byebug", "3.9.0"
14
15
 
15
16
  gemspec path: "../"
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
- gem "rails", "~> 6.0.0"
6
+ gem "rails", "~> 6.0.3"
7
7
 
8
8
  gemspec path: "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "rails", "~> 6.1.0"
7
+
8
+ gemspec path: "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "rails", "~> 7.0.0"
7
+
8
+ gemspec path: "../"
@@ -0,0 +1,200 @@
1
+ module MultiTenant
2
+ class ArelVisitorsDepthFirst < Arel::Visitors::Visitor
3
+ def initialize(block = nil)
4
+ @block = block || Proc.new
5
+ super()
6
+ end
7
+
8
+ private
9
+
10
+ def visit(o, _ = nil)
11
+ super
12
+ @block.call o
13
+ end
14
+
15
+ def unary(o)
16
+ visit o.expr
17
+ end
18
+ alias :visit_Arel_Nodes_Else :unary
19
+ alias :visit_Arel_Nodes_Group :unary
20
+ alias :visit_Arel_Nodes_Cube :unary
21
+ alias :visit_Arel_Nodes_RollUp :unary
22
+ alias :visit_Arel_Nodes_GroupingSet :unary
23
+ alias :visit_Arel_Nodes_GroupingElement :unary
24
+ alias :visit_Arel_Nodes_Grouping :unary
25
+ alias :visit_Arel_Nodes_Having :unary
26
+ alias :visit_Arel_Nodes_Lateral :unary
27
+ alias :visit_Arel_Nodes_Limit :unary
28
+ alias :visit_Arel_Nodes_Not :unary
29
+ alias :visit_Arel_Nodes_Offset :unary
30
+ alias :visit_Arel_Nodes_On :unary
31
+ alias :visit_Arel_Nodes_Ordering :unary
32
+ alias :visit_Arel_Nodes_Ascending :unary
33
+ alias :visit_Arel_Nodes_Descending :unary
34
+ alias :visit_Arel_Nodes_UnqualifiedColumn :unary
35
+ alias :visit_Arel_Nodes_OptimizerHints :unary
36
+ alias :visit_Arel_Nodes_ValuesList :unary
37
+
38
+ def function(o)
39
+ visit o.expressions
40
+ visit o.alias
41
+ visit o.distinct
42
+ end
43
+ alias :visit_Arel_Nodes_Avg :function
44
+ alias :visit_Arel_Nodes_Exists :function
45
+ alias :visit_Arel_Nodes_Max :function
46
+ alias :visit_Arel_Nodes_Min :function
47
+ alias :visit_Arel_Nodes_Sum :function
48
+
49
+ def visit_Arel_Nodes_NamedFunction(o)
50
+ visit o.name
51
+ visit o.expressions
52
+ visit o.distinct
53
+ visit o.alias
54
+ end
55
+
56
+ def visit_Arel_Nodes_Count(o)
57
+ visit o.expressions
58
+ visit o.alias
59
+ visit o.distinct
60
+ end
61
+
62
+ def visit_Arel_Nodes_Case(o)
63
+ visit o.case
64
+ visit o.conditions
65
+ visit o.default
66
+ end
67
+
68
+ def nary(o)
69
+ o.children.each { |child| visit child }
70
+ end
71
+ alias :visit_Arel_Nodes_And :nary
72
+
73
+ def binary(o)
74
+ visit o.left
75
+ visit o.right
76
+ end
77
+ alias :visit_Arel_Nodes_As :binary
78
+ alias :visit_Arel_Nodes_Assignment :binary
79
+ alias :visit_Arel_Nodes_Between :binary
80
+ alias :visit_Arel_Nodes_Concat :binary
81
+ alias :visit_Arel_Nodes_DeleteStatement :binary
82
+ alias :visit_Arel_Nodes_DoesNotMatch :binary
83
+ alias :visit_Arel_Nodes_Equality :binary
84
+ alias :visit_Arel_Nodes_FullOuterJoin :binary
85
+ alias :visit_Arel_Nodes_GreaterThan :binary
86
+ alias :visit_Arel_Nodes_GreaterThanOrEqual :binary
87
+ alias :visit_Arel_Nodes_In :binary
88
+ alias :visit_Arel_Nodes_InfixOperation :binary
89
+ alias :visit_Arel_Nodes_JoinSource :binary
90
+ alias :visit_Arel_Nodes_InnerJoin :binary
91
+ alias :visit_Arel_Nodes_LessThan :binary
92
+ alias :visit_Arel_Nodes_LessThanOrEqual :binary
93
+ alias :visit_Arel_Nodes_Matches :binary
94
+ alias :visit_Arel_Nodes_NotEqual :binary
95
+ alias :visit_Arel_Nodes_NotIn :binary
96
+ alias :visit_Arel_Nodes_NotRegexp :binary
97
+ alias :visit_Arel_Nodes_IsNotDistinctFrom :binary
98
+ alias :visit_Arel_Nodes_IsDistinctFrom :binary
99
+ alias :visit_Arel_Nodes_Or :binary
100
+ alias :visit_Arel_Nodes_OuterJoin :binary
101
+ alias :visit_Arel_Nodes_Regexp :binary
102
+ alias :visit_Arel_Nodes_RightOuterJoin :binary
103
+ alias :visit_Arel_Nodes_TableAlias :binary
104
+ alias :visit_Arel_Nodes_When :binary
105
+
106
+ def visit_Arel_Nodes_StringJoin(o)
107
+ visit o.left
108
+ end
109
+
110
+ def visit_Arel_Attribute(o)
111
+ visit o.relation
112
+ visit o.name
113
+ end
114
+ alias :visit_Arel_Attributes_Integer :visit_Arel_Attribute
115
+ alias :visit_Arel_Attributes_Float :visit_Arel_Attribute
116
+ alias :visit_Arel_Attributes_String :visit_Arel_Attribute
117
+ alias :visit_Arel_Attributes_Time :visit_Arel_Attribute
118
+ alias :visit_Arel_Attributes_Boolean :visit_Arel_Attribute
119
+ alias :visit_Arel_Attributes_Attribute :visit_Arel_Attribute
120
+ alias :visit_Arel_Attributes_Decimal :visit_Arel_Attribute
121
+
122
+ def visit_Arel_Table(o)
123
+ visit o.name
124
+ end
125
+
126
+ def terminal(o)
127
+ end
128
+ alias :visit_ActiveSupport_Multibyte_Chars :terminal
129
+ alias :visit_ActiveSupport_StringInquirer :terminal
130
+ alias :visit_Arel_Nodes_Lock :terminal
131
+ alias :visit_Arel_Nodes_Node :terminal
132
+ alias :visit_Arel_Nodes_SqlLiteral :terminal
133
+ alias :visit_Arel_Nodes_BindParam :terminal
134
+ alias :visit_Arel_Nodes_Window :terminal
135
+ alias :visit_Arel_Nodes_True :terminal
136
+ alias :visit_Arel_Nodes_False :terminal
137
+ alias :visit_BigDecimal :terminal
138
+ alias :visit_Class :terminal
139
+ alias :visit_Date :terminal
140
+ alias :visit_DateTime :terminal
141
+ alias :visit_FalseClass :terminal
142
+ alias :visit_Float :terminal
143
+ alias :visit_Integer :terminal
144
+ alias :visit_NilClass :terminal
145
+ alias :visit_String :terminal
146
+ alias :visit_Symbol :terminal
147
+ alias :visit_Time :terminal
148
+ alias :visit_TrueClass :terminal
149
+
150
+ def visit_Arel_Nodes_InsertStatement(o)
151
+ visit o.relation
152
+ visit o.columns
153
+ visit o.values
154
+ end
155
+
156
+ def visit_Arel_Nodes_SelectCore(o)
157
+ visit o.projections
158
+ visit o.source
159
+ visit o.wheres
160
+ visit o.groups
161
+ visit o.windows
162
+ visit o.havings
163
+ end
164
+
165
+ def visit_Arel_Nodes_SelectStatement(o)
166
+ visit o.cores
167
+ visit o.orders
168
+ visit o.limit
169
+ visit o.lock
170
+ visit o.offset
171
+ end
172
+
173
+ def visit_Arel_Nodes_UpdateStatement(o)
174
+ visit o.relation
175
+ visit o.values
176
+ visit o.wheres
177
+ visit o.orders
178
+ visit o.limit
179
+ end
180
+
181
+ def visit_Arel_Nodes_Comment(o)
182
+ visit o.values
183
+ end
184
+
185
+ def visit_Array(o)
186
+ o.each { |i| visit i }
187
+ end
188
+ alias :visit_Set :visit_Array
189
+
190
+ def visit_Hash(o)
191
+ o.each { |k, v| visit(k); visit(v) }
192
+ end
193
+
194
+ DISPATCH = dispatch_cache
195
+
196
+ def get_dispatch_cache
197
+ DISPATCH
198
+ end
199
+ end
200
+ end
@@ -20,10 +20,6 @@ module MultiTenant
20
20
  end
21
21
  end
22
22
 
23
- if defined?(ActionController::Base)
24
- ActionController::Base.extend MultiTenant::ControllerExtensions
25
- end
26
-
27
- if defined?(ActionController::API)
28
- ActionController::API.extend MultiTenant::ControllerExtensions
23
+ ActiveSupport.on_load(:action_controller) do |base|
24
+ base.extend MultiTenant::ControllerExtensions
29
25
  end
@@ -9,7 +9,7 @@ module MultiTenant
9
9
  end
10
10
 
11
11
  def <<(row)
12
- row = row.map.with_index { |val, idx| @column_types[idx].type_cast_for_database(val) }
12
+ row = row.map.with_index { |val, idx| @column_types[idx].serialize(val) }
13
13
  @conn.put_copy_data(row)
14
14
  @count += 1
15
15
  end
@@ -18,7 +18,7 @@ module MultiTenant
18
18
  module CopyFromClient
19
19
  def copy_from_client(columns, &block)
20
20
  conn = connection.raw_connection
21
- column_types = columns.map { |c| columns_hash[c.to_s] }
21
+ column_types = columns.map { |c| type_for_attribute(c.to_s) }
22
22
  helper = MultiTenant::CopyFromClientHelper.new(conn, column_types)
23
23
  conn.copy_data %{COPY #{quoted_table_name}("#{columns.join('","')}") FROM STDIN}, PG::TextEncoder::CopyRow.new do
24
24
  block.call helper
@@ -28,6 +28,6 @@ module MultiTenant
28
28
  end
29
29
  end
30
30
 
31
- if defined?(ActiveRecord::Base)
32
- ActiveRecord::Base.extend(MultiTenant::CopyFromClient)
31
+ ActiveSupport.on_load(:active_record) do |base|
32
+ base.extend(MultiTenant::CopyFromClient)
33
33
  end
@@ -44,10 +44,10 @@ module ActiveRecord
44
44
  module SchemaStatements
45
45
  alias :orig_create_table :create_table
46
46
  def create_table(table_name, options = {}, &block)
47
- ret = orig_create_table(table_name, options.except(:partition_key), &block)
47
+ ret = orig_create_table(table_name, **options.except(:partition_key), &block)
48
48
  if options[:partition_key] && options[:partition_key].to_s != 'id'
49
49
  execute "ALTER TABLE #{table_name} DROP CONSTRAINT #{table_name}_pkey"
50
- execute "ALTER TABLE #{table_name} ADD PRIMARY KEY(id, \"#{options[:partition_key]}\")"
50
+ execute "ALTER TABLE #{table_name} ADD PRIMARY KEY(\"#{options[:partition_key]}\", id)"
51
51
  end
52
52
  ret
53
53
  end
@@ -24,11 +24,6 @@ module MultiTenant
24
24
  def primary_key
25
25
  return @primary_key if @primary_key
26
26
 
27
- if ::ActiveRecord::VERSION::MAJOR < 5
28
- @primary_key = super || DEFAULT_ID_FIELD
29
- return @primary_key if connection.schema_cache.columns_hash(table_name).include? @primary_key
30
- end
31
-
32
27
  primary_object_keys = Array.wrap(connection.schema_cache.primary_keys(table_name)) - [partition_key]
33
28
 
34
29
  if primary_object_keys.size == 1
@@ -54,7 +49,7 @@ module MultiTenant
54
49
 
55
50
  # Create an implicit belongs_to association only if tenant class exists
56
51
  if MultiTenant.tenant_klass_defined?(tenant_name)
57
- belongs_to tenant_name, options.slice(:class_name, :inverse_of).merge(foreign_key: options[:partition_key])
52
+ belongs_to tenant_name, **options.slice(:class_name, :inverse_of).merge(foreign_key: options[:partition_key])
58
53
  end
59
54
 
60
55
  # New instances should have the tenant set
@@ -126,15 +121,20 @@ module MultiTenant
126
121
  end
127
122
  end
128
123
 
129
- if defined?(ActiveRecord::Base)
130
- ActiveRecord::Base.extend(MultiTenant::ModelExtensionsClassMethods)
124
+ ActiveSupport.on_load(:active_record) do |base|
125
+ base.extend MultiTenant::ModelExtensionsClassMethods
131
126
  end
132
127
 
133
-
134
128
  class ActiveRecord::Associations::Association
135
129
  alias skip_statement_cache_orig skip_statement_cache?
136
130
  def skip_statement_cache?(*scope)
137
131
  return true if klass.respond_to?(:scoped_by_tenant?) && klass.scoped_by_tenant?
132
+
133
+ if reflection.through_reflection
134
+ through_klass = reflection.through_reflection.klass
135
+ return true if through_klass.respond_to?(:scoped_by_tenant?) && through_klass.scoped_by_tenant?
136
+ end
137
+
138
138
  skip_statement_cache_orig(*scope)
139
139
  end
140
140
  end
@@ -34,6 +34,7 @@ module MultiTenant
34
34
  end
35
35
 
36
36
  def self.multi_tenant_model_for_arel(arel)
37
+ return nil unless arel.respond_to?(:ast)
37
38
  if arel.ast.relation.is_a? Arel::Nodes::JoinSource
38
39
  MultiTenant.multi_tenant_model_for_table(arel.ast.relation.left.table_name)
39
40
  else