activerecord-multi-tenant 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,4 +5,4 @@ source "https://rubygems.org"
5
5
  gem "appraisal"
6
6
  gem "rails", "5.2.0"
7
7
 
8
- gemspec :path => "../"
8
+ gemspec path: "../"
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- activerecord-multi-tenant (1.0.1)
5
- rails (>= 4.0)
4
+ activerecord-multi-tenant (1.0.2)
5
+ rails (>= 4.2)
6
6
  request_store (>= 1.0.5)
7
7
 
8
8
  GEM
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
- gem "rails", "4.0.13"
6
+ gem "rails", "6.0.0.rc1"
7
7
 
8
- gemspec :path => "../"
8
+ gemspec path: "../"
@@ -0,0 +1,198 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ activerecord-multi-tenant (1.0.2)
5
+ rails (>= 4.2)
6
+ request_store (>= 1.0.5)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actioncable (6.0.0.rc1)
12
+ actionpack (= 6.0.0.rc1)
13
+ nio4r (~> 2.0)
14
+ websocket-driver (>= 0.6.1)
15
+ actionmailbox (6.0.0.rc1)
16
+ actionpack (= 6.0.0.rc1)
17
+ activejob (= 6.0.0.rc1)
18
+ activerecord (= 6.0.0.rc1)
19
+ activestorage (= 6.0.0.rc1)
20
+ activesupport (= 6.0.0.rc1)
21
+ mail (>= 2.7.1)
22
+ actionmailer (6.0.0.rc1)
23
+ actionpack (= 6.0.0.rc1)
24
+ actionview (= 6.0.0.rc1)
25
+ activejob (= 6.0.0.rc1)
26
+ mail (~> 2.5, >= 2.5.4)
27
+ rails-dom-testing (~> 2.0)
28
+ actionpack (6.0.0.rc1)
29
+ actionview (= 6.0.0.rc1)
30
+ activesupport (= 6.0.0.rc1)
31
+ rack (~> 2.0)
32
+ rack-test (>= 0.6.3)
33
+ rails-dom-testing (~> 2.0)
34
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
35
+ actiontext (6.0.0.rc1)
36
+ actionpack (= 6.0.0.rc1)
37
+ activerecord (= 6.0.0.rc1)
38
+ activestorage (= 6.0.0.rc1)
39
+ activesupport (= 6.0.0.rc1)
40
+ nokogiri (>= 1.8.5)
41
+ actionview (6.0.0.rc1)
42
+ activesupport (= 6.0.0.rc1)
43
+ builder (~> 3.1)
44
+ erubi (~> 1.4)
45
+ rails-dom-testing (~> 2.0)
46
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
47
+ activejob (6.0.0.rc1)
48
+ activesupport (= 6.0.0.rc1)
49
+ globalid (>= 0.3.6)
50
+ activemodel (6.0.0.rc1)
51
+ activesupport (= 6.0.0.rc1)
52
+ activerecord (6.0.0.rc1)
53
+ activemodel (= 6.0.0.rc1)
54
+ activesupport (= 6.0.0.rc1)
55
+ activestorage (6.0.0.rc1)
56
+ actionpack (= 6.0.0.rc1)
57
+ activejob (= 6.0.0.rc1)
58
+ activerecord (= 6.0.0.rc1)
59
+ marcel (~> 0.3.1)
60
+ activesupport (6.0.0.rc1)
61
+ concurrent-ruby (~> 1.0, >= 1.0.2)
62
+ i18n (>= 0.7, < 2)
63
+ minitest (~> 5.1)
64
+ tzinfo (~> 1.1)
65
+ zeitwerk (~> 2.1, >= 2.1.4)
66
+ appraisal (2.2.0)
67
+ bundler
68
+ rake
69
+ thor (>= 0.14.0)
70
+ builder (3.2.3)
71
+ byebug (11.0.1)
72
+ coderay (1.1.2)
73
+ concurrent-ruby (1.1.5)
74
+ connection_pool (2.2.2)
75
+ crass (1.0.4)
76
+ diff-lcs (1.3)
77
+ erubi (1.8.0)
78
+ globalid (0.4.2)
79
+ activesupport (>= 4.2.0)
80
+ i18n (1.6.0)
81
+ concurrent-ruby (~> 1.0)
82
+ loofah (2.2.3)
83
+ crass (~> 1.0.2)
84
+ nokogiri (>= 1.5.9)
85
+ mail (2.7.1)
86
+ mini_mime (>= 0.1.1)
87
+ marcel (0.3.3)
88
+ mimemagic (~> 0.3.2)
89
+ method_source (0.9.2)
90
+ mimemagic (0.3.3)
91
+ mini_mime (1.0.2)
92
+ mini_portile2 (2.4.0)
93
+ minitest (5.11.3)
94
+ nio4r (2.5.1)
95
+ nokogiri (1.10.4)
96
+ mini_portile2 (~> 2.4.0)
97
+ pg (1.1.4)
98
+ pry (0.12.2)
99
+ coderay (~> 1.1.0)
100
+ method_source (~> 0.9.0)
101
+ pry-byebug (3.7.0)
102
+ byebug (~> 11.0)
103
+ pry (~> 0.10)
104
+ rack (2.0.7)
105
+ rack-protection (2.0.7)
106
+ rack
107
+ rack-test (1.1.0)
108
+ rack (>= 1.0, < 3)
109
+ rails (6.0.0.rc1)
110
+ actioncable (= 6.0.0.rc1)
111
+ actionmailbox (= 6.0.0.rc1)
112
+ actionmailer (= 6.0.0.rc1)
113
+ actionpack (= 6.0.0.rc1)
114
+ actiontext (= 6.0.0.rc1)
115
+ actionview (= 6.0.0.rc1)
116
+ activejob (= 6.0.0.rc1)
117
+ activemodel (= 6.0.0.rc1)
118
+ activerecord (= 6.0.0.rc1)
119
+ activestorage (= 6.0.0.rc1)
120
+ activesupport (= 6.0.0.rc1)
121
+ bundler (>= 1.3.0)
122
+ railties (= 6.0.0.rc1)
123
+ sprockets-rails (>= 2.0.0)
124
+ rails-dom-testing (2.0.3)
125
+ activesupport (>= 4.2.0)
126
+ nokogiri (>= 1.6)
127
+ rails-html-sanitizer (1.2.0)
128
+ loofah (~> 2.2, >= 2.2.2)
129
+ railties (6.0.0.rc1)
130
+ actionpack (= 6.0.0.rc1)
131
+ activesupport (= 6.0.0.rc1)
132
+ method_source
133
+ rake (>= 0.8.7)
134
+ thor (>= 0.20.3, < 2.0)
135
+ rake (12.3.3)
136
+ redis (4.1.2)
137
+ request_store (1.4.1)
138
+ rack (>= 1.4)
139
+ rspec (3.8.0)
140
+ rspec-core (~> 3.8.0)
141
+ rspec-expectations (~> 3.8.0)
142
+ rspec-mocks (~> 3.8.0)
143
+ rspec-core (3.8.2)
144
+ rspec-support (~> 3.8.0)
145
+ rspec-expectations (3.8.4)
146
+ diff-lcs (>= 1.2.0, < 2.0)
147
+ rspec-support (~> 3.8.0)
148
+ rspec-mocks (3.8.1)
149
+ diff-lcs (>= 1.2.0, < 2.0)
150
+ rspec-support (~> 3.8.0)
151
+ rspec-rails (3.8.2)
152
+ actionpack (>= 3.0)
153
+ activesupport (>= 3.0)
154
+ railties (>= 3.0)
155
+ rspec-core (~> 3.8.0)
156
+ rspec-expectations (~> 3.8.0)
157
+ rspec-mocks (~> 3.8.0)
158
+ rspec-support (~> 3.8.0)
159
+ rspec-support (3.8.2)
160
+ sidekiq (6.0.0)
161
+ connection_pool (>= 2.2.2)
162
+ rack (>= 2.0.0)
163
+ rack-protection (>= 2.0.0)
164
+ redis (>= 4.1.0)
165
+ sprockets (3.7.2)
166
+ concurrent-ruby (~> 1.0)
167
+ rack (> 1, < 3)
168
+ sprockets-rails (3.2.1)
169
+ actionpack (>= 4.0)
170
+ activesupport (>= 4.0)
171
+ sprockets (>= 3.0.0)
172
+ thor (0.20.3)
173
+ thread_safe (0.3.6)
174
+ tzinfo (1.2.5)
175
+ thread_safe (~> 0.1)
176
+ websocket-driver (0.7.1)
177
+ websocket-extensions (>= 0.1.0)
178
+ websocket-extensions (0.1.4)
179
+ zeitwerk (2.1.10)
180
+
181
+ PLATFORMS
182
+ ruby
183
+
184
+ DEPENDENCIES
185
+ activerecord-multi-tenant!
186
+ appraisal
187
+ pg
188
+ pry
189
+ pry-byebug
190
+ rails (= 6.0.0.rc1)
191
+ rake
192
+ rspec (>= 3.0)
193
+ rspec-rails
194
+ sidekiq
195
+ thor
196
+
197
+ BUNDLED WITH
198
+ 1.17.2
@@ -130,12 +130,11 @@ if defined?(ActiveRecord::Base)
130
130
  ActiveRecord::Base.extend(MultiTenant::ModelExtensionsClassMethods)
131
131
  end
132
132
 
133
- if ActiveRecord::VERSION::MAJOR > 4 || (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 2)
134
- class ActiveRecord::Associations::Association
135
- alias skip_statement_cache_orig skip_statement_cache?
136
- def skip_statement_cache?(*scope)
137
- return true if klass.respond_to?(:scoped_by_tenant?) && klass.scoped_by_tenant?
138
- skip_statement_cache_orig(*scope)
139
- end
133
+
134
+ class ActiveRecord::Associations::Association
135
+ alias skip_statement_cache_orig skip_statement_cache?
136
+ def skip_statement_cache?(*scope)
137
+ return true if klass.respond_to?(:scoped_by_tenant?) && klass.scoped_by_tenant?
138
+ skip_statement_cache_orig(*scope)
140
139
  end
141
140
  end
@@ -33,6 +33,14 @@ module MultiTenant
33
33
  @@multi_tenant_models[table_name.to_s]
34
34
  end
35
35
 
36
+ def self.multi_tenant_model_for_arel(arel)
37
+ if arel.ast.relation.is_a? Arel::Nodes::JoinSource
38
+ MultiTenant.multi_tenant_model_for_table(arel.ast.relation.left.table_name)
39
+ else
40
+ MultiTenant.multi_tenant_model_for_table(arel.ast.relation.table_name)
41
+ end
42
+ end
43
+
36
44
  def self.current_tenant=(tenant)
37
45
  RequestStore.store[:current_tenant] = tenant
38
46
  end
@@ -149,21 +149,27 @@ module MultiTenant
149
149
  end
150
150
  end
151
151
 
152
- class TenantEnforcementClause < Arel::Nodes::Node
152
+ class BaseTenantEnforcementClause < Arel::Nodes::Node
153
153
  attr_reader :tenant_attribute
154
154
  def initialize(tenant_attribute)
155
155
  @tenant_attribute = tenant_attribute
156
+ @tenant_model = MultiTenant.multi_tenant_model_for_table(tenant_attribute.relation.table_name)
156
157
  end
157
158
 
158
159
  def to_s; to_sql; end
159
160
  def to_str; to_sql; end
160
161
 
161
162
  def to_sql(*)
162
- tenant_arel.to_sql
163
+ collector = Arel::Collectors::SQLString.new
164
+ collector = @tenant_model.connection.visitor.accept tenant_arel, collector
165
+ collector.value
163
166
  end
164
167
 
165
- private
166
168
 
169
+ end
170
+
171
+ class TenantEnforcementClause < BaseTenantEnforcementClause
172
+ private
167
173
  def tenant_arel
168
174
  if defined?(Arel::Nodes::Quoted)
169
175
  @tenant_attribute.eq(Arel::Nodes::Quoted.new(MultiTenant.current_tenant_id))
@@ -174,24 +180,15 @@ module MultiTenant
174
180
  end
175
181
 
176
182
 
177
- class TenantJoinEnforcementClause < Arel::Nodes::Node
178
- attr_reader :tenant_attribute
183
+ class TenantJoinEnforcementClause < BaseTenantEnforcementClause
179
184
  attr_reader :table_left
180
185
  def initialize(tenant_attribute, table_left)
186
+ super(tenant_attribute)
181
187
  @table_left = table_left
182
188
  @model_left = MultiTenant.multi_tenant_model_for_table(table_left.table_name)
183
- @tenant_attribute = tenant_attribute
184
- end
185
-
186
- def to_s; to_sql; end
187
- def to_str; to_sql; end
188
-
189
- def to_sql(*)
190
- tenant_arel.to_sql
191
189
  end
192
190
 
193
191
  private
194
-
195
192
  def tenant_arel
196
193
  @tenant_attribute.eq(@table_left[@model_left.partition_key])
197
194
  end
@@ -199,23 +196,12 @@ module MultiTenant
199
196
 
200
197
 
201
198
  module TenantValueVisitor
202
- if ActiveRecord::VERSION::MAJOR > 4 || (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 2)
203
- def visit_MultiTenant_TenantEnforcementClause(o, collector)
204
- collector << o
205
- end
206
-
207
- def visit_MultiTenant_TenantJoinEnforcementClause(o, collector)
208
- collector << o
209
- end
210
-
211
- else
212
- def visit_MultiTenant_TenantEnforcementClause(o, a = nil)
213
- o
214
- end
199
+ def visit_MultiTenant_TenantEnforcementClause(o, collector)
200
+ collector << o
201
+ end
215
202
 
216
- def visit_MultiTenant_TenantJoinEnforcementClause(o, a = nil)
217
- o
218
- end
203
+ def visit_MultiTenant_TenantJoinEnforcementClause(o, collector)
204
+ collector << o
219
205
  end
220
206
  end
221
207
 
@@ -238,9 +224,9 @@ module MultiTenant
238
224
  delete
239
225
  end
240
226
 
241
- if ActiveRecord::VERSION::MAJOR >= 5 && ActiveRecord::VERSION::MINOR >= 2
227
+ if (ActiveRecord::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR >= 2) || ActiveRecord::VERSION::MAJOR > 5
242
228
  def update(arel, name = nil, binds = [])
243
- model = MultiTenant.multi_tenant_model_for_table(arel.ast.relation.table_name)
229
+ model = MultiTenant.multi_tenant_model_for_arel(arel)
244
230
  if model.present? && !MultiTenant.with_write_only_mode_enabled? && MultiTenant.current_tenant_id.present?
245
231
  arel.where(MultiTenant::TenantEnforcementClause.new(model.arel_table[model.partition_key]))
246
232
  end
@@ -248,7 +234,7 @@ module MultiTenant
248
234
  end
249
235
 
250
236
  def delete(arel, name = nil, binds = [])
251
- model = MultiTenant.multi_tenant_model_for_table(arel.ast.left.table_name)
237
+ model = MultiTenant.multi_tenant_model_for_arel(arel)
252
238
  if model.present? && !MultiTenant.with_write_only_mode_enabled? && MultiTenant.current_tenant_id.present?
253
239
  arel.where(MultiTenant::TenantEnforcementClause.new(model.arel_table[model.partition_key]))
254
240
  end
@@ -296,7 +282,6 @@ module ActiveRecord
296
282
  end
297
283
 
298
284
  if node.is_a?(Arel::Nodes::SelectCore) || node.is_a?(Arel::Nodes::Join)
299
-
300
285
  if node.is_a?Arel::Nodes::Join
301
286
  node_list = [node]
302
287
  else
@@ -304,14 +289,18 @@ module ActiveRecord
304
289
  end
305
290
 
306
291
  node_list.select{ |n| n.is_a? Arel::Nodes::Join }.each do |node_join|
307
- if !node_join.right || !node_join.right.expr.right.is_a?(Arel::Attributes::Attribute)
292
+ if (!node_join.right ||
293
+ (ActiveRecord::VERSION::MAJOR <= 5 &&
294
+ !node_join.right.expr.right.is_a?(Arel::Attributes::Attribute)))
308
295
  next
309
296
  end
310
297
 
311
- relation_right = node_join.right.expr.right.relation
312
- relation_left = node_join.right.expr.left.relation
313
- model_left = MultiTenant.multi_tenant_model_for_table(relation_right.table_name)
298
+ relation_right, relation_left = relations_from_node_join(node_join)
299
+
300
+ next unless relation_right && relation_left
301
+
314
302
  model_right = MultiTenant.multi_tenant_model_for_table(relation_left.table_name)
303
+ model_left = MultiTenant.multi_tenant_model_for_table(relation_right.table_name)
315
304
  if model_right && model_left
316
305
  join_enforcement_clause = MultiTenant::TenantJoinEnforcementClause.new(relation_left[model_left.partition_key], relation_right)
317
306
  node_join.right.expr = node_join.right.expr.and(join_enforcement_clause)
@@ -324,6 +313,22 @@ module ActiveRecord
324
313
 
325
314
  arel
326
315
  end
316
+
317
+ private
318
+ def relations_from_node_join(node_join)
319
+ if ActiveRecord::VERSION::MAJOR <= 5 || node_join.right.expr.is_a?(Arel::Nodes::Equality)
320
+ return node_join.right.expr.right.relation, node_join.right.expr.left.relation
321
+ end
322
+
323
+ children = node_join.right.expr.children
324
+
325
+ tenant_applied = children.any?(MultiTenant::TenantEnforcementClause) || children.any?(MultiTenant::TenantJoinEnforcementClause)
326
+ if tenant_applied || children.empty?
327
+ return nil, nil
328
+ end
329
+
330
+ return children[0].right.relation, children[0].left.relation
331
+ end
327
332
  end
328
333
  end
329
334
 
@@ -1,3 +1,3 @@
1
1
  module MultiTenant
2
- VERSION = '1.0.1'
2
+ VERSION = '1.0.2'
3
3
  end
@@ -348,11 +348,7 @@ describe MultiTenant do
348
348
  end
349
349
 
350
350
  it "applies the team_id conditions in the where clause" do
351
- expected_sql = if uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR < 2
352
- <<-sql
353
- SELECT "sub_tasks".* FROM "sub_tasks" INNER JOIN "tasks" ON "sub_tasks"."task_id" = "tasks"."id" AND "sub_tasks"."account_id" = "tasks"."account_id" WHERE "tasks"."account_id" = 1 AND "sub_tasks"."account_id" = 1 AND "tasks"."project_id" = $1
354
- sql
355
- elsif uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR == 0
351
+ expected_sql = if uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR == 0
356
352
  <<-sql
357
353
  SELECT "sub_tasks".* FROM "sub_tasks" INNER JOIN "tasks" ON "sub_tasks"."task_id" = "tasks"."id" AND "sub_tasks"."account_id" = "tasks"."account_id" WHERE "tasks"."account_id" = 1 AND "tasks"."project_id" = 1
358
354
  sql
@@ -361,27 +357,21 @@ describe MultiTenant do
361
357
  SELECT "sub_tasks".* FROM "sub_tasks" INNER JOIN "tasks" ON "sub_tasks"."task_id" = "tasks"."id" AND "sub_tasks"."account_id" = "tasks"."account_id" WHERE "tasks"."account_id" = 1 AND "sub_tasks"."account_id" = 1 AND "tasks"."project_id" = 1
362
358
  sql
363
359
  end
360
+
364
361
  account1 = Account.create! name: 'Account 1'
365
362
 
366
363
  MultiTenant.with(account1) do
367
364
  project1 = Project.create! name: 'Project 1'
368
365
  task1 = Task.create! name: 'Task 1', project: project1
369
366
  subtask1 = SubTask.create! task: task1
370
-
371
367
  expect(project1.sub_tasks.to_sql).to eq(expected_sql.strip)
372
368
  expect(project1.sub_tasks).to include(subtask1)
373
369
  end
374
370
 
375
371
  MultiTenant.without do
376
- expected_sql = if uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR < 2
377
- <<-sql
378
- SELECT "sub_tasks".* FROM "sub_tasks" INNER JOIN "tasks" ON "sub_tasks"."task_id" = "tasks"."id" AND "sub_tasks"."account_id" = "tasks"."account_id" WHERE "tasks"."project_id" = $1
379
- sql
380
- else
381
- <<-sql
382
- SELECT "sub_tasks".* FROM "sub_tasks" INNER JOIN "tasks" ON "sub_tasks"."task_id" = "tasks"."id" AND "sub_tasks"."account_id" = "tasks"."account_id" WHERE "tasks"."project_id" = 1
372
+ expected_sql = <<-sql
373
+ SELECT "sub_tasks".* FROM "sub_tasks" INNER JOIN "tasks" ON "sub_tasks"."task_id" = "tasks"."id" AND "sub_tasks"."account_id" = "tasks"."account_id" WHERE "tasks"."project_id" = 1
383
374
  sql
384
- end
385
375
 
386
376
  project = Project.first
387
377
  expect(project.sub_tasks.to_sql).to eq(expected_sql.strip)
@@ -389,43 +379,33 @@ describe MultiTenant do
389
379
  end
390
380
 
391
381
  it "tests joins between distributed and reference table" do
392
- expected_sql = if uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR < 2
393
- <<-sql
394
- SELECT "categories".* FROM "categories" INNER JOIN "project_categories" ON "categories"."id" = "project_categories"."category_id" WHERE "project_categories"."account_id" = 1 AND "project_categories"."project_id" = $1
395
- sql
396
- else
397
- <<-sql
382
+ expected_sql = <<-sql
398
383
  SELECT "categories".* FROM "categories" INNER JOIN "project_categories" ON "categories"."id" = "project_categories"."category_id" WHERE "project_categories"."account_id" = 1 AND "project_categories"."project_id" = 1
399
- sql
400
- end
384
+ sql
401
385
  account1 = Account.create! name: 'Account 1'
402
386
  category1 = Category.create! name: 'Category 1'
403
387
 
404
388
  MultiTenant.with(account1) do
405
389
  project1 = Project.create! name: 'Project 1'
406
390
  projectcategory = ProjectCategory.create! name: 'project cat 1', project: project1, category: category1
391
+
407
392
  expect(project1.categories.to_sql).to eq(expected_sql.strip)
408
393
  expect(project1.categories).to include(category1)
409
394
  expect(project1.project_categories).to include(projectcategory)
410
395
  end
411
396
 
412
397
  MultiTenant.without do
413
- expected_sql = if uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR < 2
414
- <<-sql
415
- SELECT "categories".* FROM "categories" INNER JOIN "project_categories" ON "categories"."id" = "project_categories"."category_id" WHERE "project_categories"."project_id" = $1
416
- sql
417
- else
418
- <<-sql
398
+ expected_sql = <<-sql
419
399
  SELECT "categories".* FROM "categories" INNER JOIN "project_categories" ON "categories"."id" = "project_categories"."category_id" WHERE "project_categories"."project_id" = 1
420
400
  sql
421
- end
401
+
422
402
  project = Project.first
423
403
  expect(project.categories.to_sql).to eq(expected_sql.strip)
424
404
  expect(project.categories).to include(category1)
425
405
 
426
406
  expected_sql = <<-sql
427
407
  SELECT "projects".* FROM "projects" INNER JOIN "project_categories" ON "project_categories"."project_id" = "projects"."id" AND "project_categories"."account_id" = "projects"."account_id" INNER JOIN "categories" ON "categories"."id" = "project_categories"."category_id" WHERE "projects"."account_id" = 1
428
- sql
408
+ sql
429
409
 
430
410
  expect(Project.where(account_id: 1).joins(:categories).to_sql).to eq(expected_sql.strip)
431
411
  project = Project.where(account_id: 1).joins(:categories).first
@@ -442,9 +422,9 @@ describe MultiTenant do
442
422
  <<-sql
443
423
  SELECT "projects"."id" AS t0_r0, "projects"."account_id" AS t0_r1, "projects"."name" AS t0_r2, "categories"."id" AS t1_r0, "categories"."name" AS t1_r1 FROM "projects" LEFT OUTER JOIN "project_categories" ON "project_categories"."project_id" = "projects"."id" AND "project_categories"."account_id" = 1 AND "projects"."account_id" = 1 LEFT OUTER JOIN "categories" ON "categories"."id" = "project_categories"."category_id" AND "project_categories"."account_id" = 1 WHERE "projects"."account_id" = 1
444
424
  sql
445
- elsif uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 0
425
+ elsif uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 6
446
426
  <<-sql
447
- SELECT "projects".* FROM "projects" WHERE "projects"."account_id" = 1
427
+ SELECT "projects"."id" AS t0_r0, "projects"."account_id" AS t0_r1, "projects"."name" AS t0_r2, "categories"."id" AS t1_r0, "categories"."name" AS t1_r1 FROM "projects" LEFT OUTER JOIN "project_categories" ON "project_categories"."account_id" = 1 AND "project_categories"."project_id" = "projects"."id" AND "projects"."account_id" = 1 LEFT OUTER JOIN "categories" ON "categories"."id" = "project_categories"."category_id" AND "project_categories"."account_id" = 1 WHERE "projects"."account_id" = 1
448
428
  sql
449
429
  else
450
430
  <<-sql
@@ -464,15 +444,9 @@ describe MultiTenant do
464
444
  end
465
445
 
466
446
  MultiTenant.without do
467
- expected_sql = if uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 0
468
- <<-sql
469
- SELECT "projects".* FROM "projects" WHERE "projects"."account_id" = 1
470
- sql
471
- else
472
- <<-sql
447
+ expected_sql = <<-sql
473
448
  SELECT "projects"."id" AS t0_r0, "projects"."account_id" AS t0_r1, "projects"."name" AS t0_r2, "categories"."id" AS t1_r0, "categories"."name" AS t1_r1 FROM "projects" LEFT OUTER JOIN "project_categories" ON "project_categories"."project_id" = "projects"."id" AND "project_categories"."account_id" = "projects"."account_id" LEFT OUTER JOIN "categories" ON "categories"."id" = "project_categories"."category_id" WHERE "projects"."account_id" = 1
474
- sql
475
- end
449
+ sql
476
450
 
477
451
  expect(Project.where(account_id: 1).eager_load(:categories).to_sql).to eq(expected_sql.strip)
478
452
 
@@ -491,6 +465,10 @@ describe MultiTenant do
491
465
  <<-sql
492
466
  SELECT "tasks".* FROM "tasks" INNER JOIN "projects" ON "projects"."id" = "tasks"."project_id" AND "projects"."account_id" = 1 LEFT JOIN project_categories pc ON project.category_id = pc.id WHERE "tasks"."account_id" = 1
493
467
  sql
468
+ elsif uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 6
469
+ <<-sql
470
+ SELECT "tasks".* FROM "tasks" INNER JOIN "projects" ON "projects"."account_id" = 1 AND "projects"."id" = "tasks"."project_id" LEFT JOIN project_categories pc ON project.category_id = pc.id WHERE "tasks"."account_id" = 1
471
+ sql
494
472
  else
495
473
  <<-sql
496
474
  SELECT "tasks".* FROM "tasks" INNER JOIN "projects" ON "projects"."id" = "tasks"."project_id" AND "projects"."account_id" = "tasks"."account_id" LEFT JOIN project_categories pc ON project.category_id = pc.id WHERE "projects"."account_id" = 1 AND "tasks"."account_id" = 1
@@ -501,7 +479,6 @@ describe MultiTenant do
501
479
  projectcategory = ProjectCategory.create! name: 'project cat 1', project: project1, category: category1
502
480
 
503
481
  project1.tasks.create! name: 'baz'
504
-
505
482
  expect(Task.joins(:project).joins('LEFT JOIN project_categories pc ON project.category_id = pc.id').to_sql).to eq(expected_sql.strip)
506
483
  end
507
484
 
@@ -509,73 +486,76 @@ describe MultiTenant do
509
486
  expected_sql = <<-sql
510
487
  SELECT "tasks".* FROM "tasks" INNER JOIN "projects" ON "projects"."id" = "tasks"."project_id" AND "projects"."account_id" = "tasks"."account_id" LEFT JOIN project_categories pc ON project.category_id = pc.id WHERE "tasks"."account_id" = 1
511
488
  sql
489
+
512
490
  expect(Task.where(account_id: 1).joins(:project).joins('LEFT JOIN project_categories pc ON project.category_id = pc.id').to_sql).to eq(expected_sql.strip)
513
491
 
514
492
  end
515
493
 
516
494
  end
517
495
 
496
+ it "only applies clauses when a tenant is set" do
497
+ account = Account.create! name: 'Account 1'
498
+ project = Project.create! name: 'Project 1', account: account
499
+ project2 = Project.create! name: 'Project 2', account: Account.create!(name: 'Account2')
518
500
 
519
-
520
- # Versions earlier than 4.2 pass an arel object to find_by_sql(...) and it would make
521
- # this test unnecesssarily complicated to support that
522
- if ActiveRecord::VERSION::MAJOR > 4 || (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 2)
523
- it "only applies clauses when a tenant is set" do
524
- account = Account.create! name: 'Account 1'
525
- project = Project.create! name: 'Project 1', account: account
526
- project2 = Project.create! name: 'Project 2', account: Account.create!(name: 'Account2')
527
-
528
- MultiTenant.with(account) do
529
- expected_sql = if uses_prepared_statements? && ActiveRecord::VERSION::MAJOR > 4
530
- <<-sql.strip
501
+ MultiTenant.with(account) do
502
+ expected_sql = if uses_prepared_statements? && ActiveRecord::VERSION::MAJOR > 5
503
+ <<-sql.strip
504
+ SELECT "projects".* FROM "projects" WHERE "projects"."account_id" = #{account.id} AND "projects"."id" = $1 LIMIT $2
505
+ sql
506
+ elsif uses_prepared_statements? && ActiveRecord::VERSION::MAJOR > 4
507
+ <<-sql.strip
531
508
  SELECT "projects".* FROM "projects" WHERE "projects"."account_id" = #{account.id} AND "projects"."id" = $1 LIMIT $2
532
509
  sql
533
- elsif uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 4
534
- <<-sql.strip
510
+ elsif uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 4
511
+ <<-sql.strip
535
512
  SELECT "projects".* FROM "projects" WHERE "projects"."account_id" = #{account.id} AND "projects"."id" = $1 LIMIT 1
536
513
  sql
537
- else
538
- <<-sql.strip
514
+ else
515
+ <<-sql.strip
539
516
  SELECT "projects".* FROM "projects" WHERE "projects"."account_id" = #{account.id} AND "projects"."id" = #{project.id} LIMIT 1
540
517
  sql
541
- end
542
- expect(Project).to receive(:find_by_sql).with(expected_sql, any_args).and_call_original
543
- expect(Project.find(project.id)).to eq(project)
544
- end
518
+ end
545
519
 
546
- MultiTenant.without do
547
- expected_sql = if uses_prepared_statements? && ActiveRecord::VERSION::MAJOR > 4
548
- <<-sql.strip
520
+ expect(Project).to receive(:find_by_sql).with(expected_sql, any_args).and_call_original
521
+ expect(Project.find(project.id)).to eq(project)
522
+ end
523
+
524
+ MultiTenant.without do
525
+ expected_sql = if uses_prepared_statements? && ActiveRecord::VERSION::MAJOR > 5
526
+ <<-sql.strip
527
+ SELECT "projects".* FROM "projects" WHERE "projects"."id" = $1 LIMIT $2
528
+ sql
529
+ elsif uses_prepared_statements? && ActiveRecord::VERSION::MAJOR > 4
530
+ <<-sql.strip
549
531
  SELECT "projects".* FROM "projects" WHERE "projects"."id" = $1 LIMIT $2
550
532
  sql
551
- elsif uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 4
552
- <<-sql.strip
533
+ elsif uses_prepared_statements? && ActiveRecord::VERSION::MAJOR == 4
534
+ <<-sql.strip
553
535
  SELECT "projects".* FROM "projects" WHERE "projects"."id" = $1 LIMIT 1
554
536
  sql
555
- else
556
- <<-sql.strip
537
+ else
538
+ <<-sql.strip
557
539
  SELECT "projects".* FROM "projects" WHERE "projects"."id" = #{project2.id} LIMIT 1
558
540
  sql
559
- end
560
- expect(Project).to receive(:find_by_sql).with(expected_sql, any_args).and_call_original
561
- expect(Project.find(project2.id)).to eq(project2)
562
- end
541
+ end
542
+
543
+ expect(Project).to receive(:find_by_sql).with(expected_sql, any_args).and_call_original
544
+ expect(Project.find(project2.id)).to eq(project2)
563
545
  end
564
546
  end
565
547
 
566
- # Versions earlier than 4.1 have a different behaviour regarding unsaved associations
567
- if ActiveRecord::VERSION::MAJOR > 4 || (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 1)
568
- describe 'with unsaved association' do
569
- before do
570
- @account = Account.create!(name: 'reflection tenant')
571
- @manager = Manager.new(account: @account)
572
- MultiTenant.current_tenant = @account
573
- @account.update! name: 'reflection tenant update'
574
- end
575
548
 
576
- it 'persists the reflected association' do
577
- expect(@manager.persisted?).to eq(true)
578
- end
549
+ describe 'with unsaved association' do
550
+ before do
551
+ @account = Account.create!(name: 'reflection tenant')
552
+ @manager = Manager.new(account: @account)
553
+ MultiTenant.current_tenant = @account
554
+ @account.update! name: 'reflection tenant update'
555
+ end
556
+
557
+ it 'persists the reflected association' do
558
+ expect(@manager.persisted?).to eq(true)
579
559
  end
580
560
  end
581
561