activerecord-multi-tenant 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/CI.yml +63 -0
- data/.gitignore +2 -0
- data/.rspec +1 -0
- data/Appraisals +8 -0
- data/CHANGELOG.md +8 -0
- data/gemfiles/active_record_5.2.gemfile +1 -1
- data/gemfiles/active_record_7.0.gemfile +8 -0
- data/gemfiles/rails_5.2.gemfile +1 -1
- data/gemfiles/rails_7.0.gemfile +8 -0
- data/lib/activerecord-multi-tenant/copy_from_client.rb +2 -2
- data/lib/activerecord-multi-tenant/query_rewriter.rb +7 -1
- data/lib/activerecord-multi-tenant/sidekiq.rb +5 -1
- data/lib/activerecord-multi-tenant/version.rb +1 -1
- data/spec/activerecord-multi-tenant/model_extensions_spec.rb +58 -50
- data/spec/activerecord-multi-tenant/query_rewriter_spec.rb +17 -0
- data/spec/activerecord-multi-tenant/sidekiq_spec.rb +11 -0
- data/spec/schema.rb +27 -4
- metadata +10 -14
- data/.travis.yml +0 -34
- data/Gemfile.lock +0 -199
- data/gemfiles/active_record_5.2.gemfile.lock +0 -188
- data/gemfiles/active_record_6.0.gemfile.lock +0 -198
- data/gemfiles/active_record_6.1.gemfile.lock +0 -198
- data/gemfiles/rails_5.2.gemfile.lock +0 -188
- data/gemfiles/rails_6.0.gemfile.lock +0 -198
- data/gemfiles/rails_6.1.gemfile.lock +0 -198
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa2e595cc76e33a877613504121106791680118da0a0c4957ff1190e75e99c3a
|
4
|
+
data.tar.gz: 8a232e3431462d5b8b3972f0825664c210cc51729b2e94d08c5529851365d7f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--force-color
|
data/Appraisals
CHANGED
@@ -18,6 +18,10 @@ appraise 'rails-6.1' do
|
|
18
18
|
gem 'rails', '~> 6.1.0'
|
19
19
|
end
|
20
20
|
|
21
|
+
appraise 'rails-7.0' do
|
22
|
+
gem 'rails', '~> 7.0.0'
|
23
|
+
end
|
24
|
+
|
21
25
|
appraise 'active-record-5.2' do
|
22
26
|
gem 'activerecord', '~> 5.2.0'
|
23
27
|
gem 'i18n', '~> 0.9.5'
|
@@ -37,3 +41,7 @@ end
|
|
37
41
|
appraise 'active-record-6.1' do
|
38
42
|
gem 'activerecord', '~> 6.1.0'
|
39
43
|
end
|
44
|
+
|
45
|
+
appraise 'active-record-7.0' do
|
46
|
+
gem 'activerecord', '~> 7.0.0'
|
47
|
+
end
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
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
|
+
|
3
11
|
## 1.1.1 2021-01-15
|
4
12
|
|
5
13
|
* Add support for Rails 6.1 [#108](https://github.com/citusdata/activerecord-multi-tenant/pull/108)
|
data/gemfiles/rails_5.2.gemfile
CHANGED
@@ -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].
|
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|
|
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
|
@@ -122,6 +122,8 @@ module MultiTenant
|
|
122
122
|
alias :visit_Arel_Nodes_FullOuterJoin :visit_Arel_Nodes_OuterJoin
|
123
123
|
alias :visit_Arel_Nodes_RightOuterJoin :visit_Arel_Nodes_OuterJoin
|
124
124
|
|
125
|
+
alias :visit_ActiveModel_Attribute :terminal
|
126
|
+
|
125
127
|
private
|
126
128
|
|
127
129
|
def tenant_relation?(table_name)
|
@@ -274,7 +276,11 @@ module ActiveRecord
|
|
274
276
|
if node.wheres.empty?
|
275
277
|
node.wheres = [enforcement_clause]
|
276
278
|
else
|
277
|
-
node.wheres[0]
|
279
|
+
if node.wheres[0].is_a?(Arel::Nodes::And)
|
280
|
+
node.wheres[0].children << enforcement_clause
|
281
|
+
else
|
282
|
+
node.wheres[0] = enforcement_clause.and(node.wheres[0])
|
283
|
+
end
|
278
284
|
end
|
279
285
|
else
|
280
286
|
raise "UnknownContext"
|
@@ -18,7 +18,11 @@ module Sidekiq::Middleware::MultiTenant
|
|
18
18
|
class Server
|
19
19
|
def call(worker_class, msg, queue)
|
20
20
|
if msg.has_key?('multi_tenant')
|
21
|
-
tenant =
|
21
|
+
tenant = begin
|
22
|
+
msg['multi_tenant']['class'].constantize.find(msg['multi_tenant']['id'])
|
23
|
+
rescue ActiveRecord::RecordNotFound
|
24
|
+
msg['multi_tenant']['id']
|
25
|
+
end
|
22
26
|
MultiTenant.with(tenant) do
|
23
27
|
yield
|
24
28
|
end
|
@@ -348,9 +348,12 @@ describe MultiTenant do
|
|
348
348
|
end
|
349
349
|
|
350
350
|
it "applies the team_id conditions in the where clause" do
|
351
|
-
|
352
|
-
|
353
|
-
|
351
|
+
option1 = <<-sql.strip
|
352
|
+
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 AND "sub_tasks"."account_id" = 1 AND "tasks"."account_id" = 1
|
353
|
+
sql
|
354
|
+
option2 = <<-sql.strip
|
355
|
+
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 "sub_tasks"."account_id" = 1 AND "tasks"."project_id" = 1 AND "tasks"."account_id" = 1
|
356
|
+
sql
|
354
357
|
|
355
358
|
account1 = Account.create! name: 'Account 1'
|
356
359
|
|
@@ -358,7 +361,7 @@ describe MultiTenant do
|
|
358
361
|
project1 = Project.create! name: 'Project 1'
|
359
362
|
task1 = Task.create! name: 'Task 1', project: project1
|
360
363
|
subtask1 = SubTask.create! task: task1
|
361
|
-
expect(project1.sub_tasks.to_sql).to eq(
|
364
|
+
expect(project1.sub_tasks.to_sql).to eq(option1).or(eq(option2))
|
362
365
|
expect(project1.sub_tasks).to include(subtask1)
|
363
366
|
end
|
364
367
|
|
@@ -373,9 +376,13 @@ describe MultiTenant do
|
|
373
376
|
end
|
374
377
|
|
375
378
|
it "tests joins between distributed and reference table" do
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
+
option1 = <<-sql.strip
|
380
|
+
SELECT "categories".* FROM "categories" INNER JOIN "project_categories" ON "categories"."id" = "project_categories"."category_id" WHERE "project_categories"."project_id" = 1 AND "project_categories"."account_id" = 1
|
381
|
+
sql
|
382
|
+
option2 = <<-sql.strip
|
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
|
384
|
+
sql
|
385
|
+
|
379
386
|
account1 = Account.create! name: 'Account 1'
|
380
387
|
category1 = Category.create! name: 'Category 1'
|
381
388
|
|
@@ -383,7 +390,7 @@ describe MultiTenant do
|
|
383
390
|
project1 = Project.create! name: 'Project 1'
|
384
391
|
projectcategory = ProjectCategory.create! name: 'project cat 1', project: project1, category: category1
|
385
392
|
|
386
|
-
expect(project1.categories.to_sql).to eq(
|
393
|
+
expect(project1.categories.to_sql).to eq(option1).or(eq(option2))
|
387
394
|
expect(project1.categories).to include(category1)
|
388
395
|
expect(project1.project_categories).to include(projectcategory)
|
389
396
|
end
|
@@ -412,21 +419,18 @@ describe MultiTenant do
|
|
412
419
|
account1 = Account.create! name: 'Account 1'
|
413
420
|
category1 = Category.create! name: 'Category 1'
|
414
421
|
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
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
|
422
|
-
sql
|
423
|
-
end
|
422
|
+
option1 = <<-sql.strip
|
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
|
424
|
+
sql
|
425
|
+
option2 = <<-sql.strip
|
426
|
+
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
|
427
|
+
sql
|
424
428
|
|
425
429
|
MultiTenant.with(account1) do
|
426
430
|
project1 = Project.create! name: 'Project 1'
|
427
431
|
projectcategory = ProjectCategory.create! name: 'project cat 1', project: project1, category: category1
|
428
432
|
|
429
|
-
expect(Project.eager_load(:categories).to_sql).to eq(
|
433
|
+
expect(Project.eager_load(:categories).to_sql).to eq(option1).or(eq(option2))
|
430
434
|
|
431
435
|
project = Project.eager_load(:categories).first
|
432
436
|
expect(project.categories).to include(category1)
|
@@ -451,21 +455,18 @@ describe MultiTenant do
|
|
451
455
|
category1 = Category.create! name: 'Category 1'
|
452
456
|
|
453
457
|
MultiTenant.with(account1) do
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
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
|
461
|
-
sql
|
462
|
-
end
|
458
|
+
option1 = <<-sql.strip
|
459
|
+
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
|
460
|
+
sql
|
461
|
+
option2 = <<-sql.strip
|
462
|
+
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
|
463
|
+
sql
|
463
464
|
|
464
465
|
project1 = Project.create! name: 'Project 1'
|
465
466
|
projectcategory = ProjectCategory.create! name: 'project cat 1', project: project1, category: category1
|
466
467
|
|
467
468
|
project1.tasks.create! name: 'baz'
|
468
|
-
expect(Task.joins(:project).joins('LEFT JOIN project_categories pc ON project.category_id = pc.id').to_sql).to eq(
|
469
|
+
expect(Task.joins(:project).joins('LEFT JOIN project_categories pc ON project.category_id = pc.id').to_sql).to eq(option1).or(eq(option2))
|
469
470
|
end
|
470
471
|
|
471
472
|
MultiTenant.without do
|
@@ -485,32 +486,39 @@ describe MultiTenant do
|
|
485
486
|
project2 = Project.create! name: 'Project 2', account: Account.create!(name: 'Account2')
|
486
487
|
|
487
488
|
MultiTenant.with(account) do
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
489
|
+
option1 = <<-sql.strip
|
490
|
+
SELECT "projects".* FROM "projects" WHERE "projects"."account_id" = #{account.id} AND "projects"."id" = $1 LIMIT $2
|
491
|
+
sql
|
492
|
+
option2 = <<-sql.strip
|
493
|
+
SELECT "projects".* FROM "projects" WHERE "projects"."id" = $1 AND "projects"."account_id" = #{account.id} LIMIT $2
|
494
|
+
sql
|
495
|
+
option3 = <<-sql.strip
|
496
|
+
SELECT "projects".* FROM "projects" WHERE "projects"."id" = $1 AND "projects"."account_id" = #{account.id} LIMIT $2
|
497
|
+
sql
|
498
|
+
|
499
|
+
# Couldn't make the following line pass for some reason, so came up with an uglier alternative
|
500
|
+
# expect(Project).to receive(:find_by_sql).with(eq(option1).or(eq(option2)).or(eq(option3)), any_args).and_call_original
|
501
|
+
expect(Project).to receive(:find_by_sql).and_wrap_original do |m, *args|
|
502
|
+
expect(args[0]).to(eq(option1).or(eq(option2)).or(eq(option3)))
|
503
|
+
m.call(args[0], args[1], preparable:args[2][:preparable])
|
504
|
+
end
|
499
505
|
expect(Project.find(project.id)).to eq(project)
|
500
506
|
end
|
501
507
|
|
502
508
|
MultiTenant.without do
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
509
|
+
option1 = <<-sql.strip
|
510
|
+
SELECT "projects".* FROM "projects" WHERE "projects"."id" = $1 LIMIT $2
|
511
|
+
sql
|
512
|
+
option2 = <<-sql.strip
|
513
|
+
SELECT "projects".* FROM "projects" WHERE "projects"."id" = $1 LIMIT $2
|
514
|
+
sql
|
515
|
+
|
516
|
+
# Couldn't make the following line pass for some reason, so came up with an uglier alternative
|
517
|
+
# expect(Project).to receive(:find_by_sql).with(eq(option1).or(eq(option2)), any_args).and_call_original
|
518
|
+
expect(Project).to receive(:find_by_sql).and_wrap_original do |m, *args|
|
519
|
+
expect(args[0]).to(eq(option1).or(eq(option2)))
|
520
|
+
m.call(args[0], args[1], preparable:args[2][:preparable])
|
521
|
+
end
|
514
522
|
expect(Project.find(project2.id)).to eq(project2)
|
515
523
|
end
|
516
524
|
end
|
@@ -98,4 +98,21 @@ describe "Query Rewriter" do
|
|
98
98
|
}.not_to raise_error
|
99
99
|
end
|
100
100
|
end
|
101
|
+
|
102
|
+
context "when joining with a model with a default scope" do
|
103
|
+
let!(:account) { Account.create!(name: "Test Account") }
|
104
|
+
|
105
|
+
it "fetches only records within the default scope" do
|
106
|
+
alive = Domain.create(name: "alive", account: account)
|
107
|
+
deleted = Domain.create(name: "deleted", deleted: true, account: account)
|
108
|
+
page_in_alive_domain = Page.create(name: "alive", account: account, domain: alive)
|
109
|
+
page_in_deleted_domain = Page.create(name: "deleted", account: account, domain: deleted)
|
110
|
+
|
111
|
+
expect(
|
112
|
+
MultiTenant.with(account) do
|
113
|
+
Page.joins(:domain).pluck(:id)
|
114
|
+
end
|
115
|
+
).to eq([page_in_alive_domain.id])
|
116
|
+
end
|
117
|
+
end
|
101
118
|
end
|
@@ -5,6 +5,9 @@ require 'activerecord-multi-tenant/sidekiq'
|
|
5
5
|
describe MultiTenant, 'Sidekiq' do
|
6
6
|
let(:server) { Sidekiq::Middleware::MultiTenant::Server.new }
|
7
7
|
let(:account) { Account.create(name: 'test') }
|
8
|
+
let(:deleted_acount) { Account.create(name: 'deleted') }
|
9
|
+
|
10
|
+
before { deleted_acount.destroy! }
|
8
11
|
|
9
12
|
describe 'server middleware' do
|
10
13
|
it 'sets the multitenant context when provided in message' do
|
@@ -15,6 +18,14 @@ describe MultiTenant, 'Sidekiq' do
|
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
21
|
+
it 'sets the multitenant context (id) even if tenant not found' do
|
22
|
+
server.call(double,{'bogus' => 'message',
|
23
|
+
'multi_tenant' => { 'class' => deleted_acount.class.name, 'id' => deleted_acount.id}},
|
24
|
+
'bogus_queue') do
|
25
|
+
expect(MultiTenant.current_tenant).to eq(deleted_acount.id)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
18
29
|
it 'does not set the multitenant context when no tenant provided' do
|
19
30
|
server.call(double, {'bogus' => 'message'}, 'bogus_queue') do
|
20
31
|
expect(MultiTenant.current_tenant).to be_nil
|
data/spec/schema.rb
CHANGED
@@ -89,10 +89,21 @@ ARGV.grep(/\w+_spec\.rb/).empty? && ActiveRecord::Schema.define(version: 1) do
|
|
89
89
|
t.column :category_id, :integer
|
90
90
|
end
|
91
91
|
|
92
|
-
|
93
92
|
create_table :allowed_places, force: true, id: false do |t|
|
94
|
-
|
95
|
-
|
93
|
+
t.string :account_id, :integer
|
94
|
+
t.string :name, :string
|
95
|
+
end
|
96
|
+
|
97
|
+
create_table :domains, force: true, partition_key: :account_id do |t|
|
98
|
+
t.column :account_id, :integer
|
99
|
+
t.column :name, :string
|
100
|
+
t.column :deleted, :boolean, default: false
|
101
|
+
end
|
102
|
+
|
103
|
+
create_table :pages, force: true, partition_key: :account_id do |t|
|
104
|
+
t.column :account_id, :integer
|
105
|
+
t.column :name, :string
|
106
|
+
t.column :domain_id, :integer
|
96
107
|
end
|
97
108
|
|
98
109
|
create_distributed_table :accounts, :id
|
@@ -108,6 +119,8 @@ ARGV.grep(/\w+_spec\.rb/).empty? && ActiveRecord::Schema.define(version: 1) do
|
|
108
119
|
create_distributed_table :uuid_records, :organization_id
|
109
120
|
create_distributed_table :project_categories, :account_id
|
110
121
|
create_distributed_table :allowed_places, :account_id
|
122
|
+
create_distributed_table :domains, :account_id
|
123
|
+
create_distributed_table :pages, :account_id
|
111
124
|
create_reference_table :categories
|
112
125
|
end
|
113
126
|
|
@@ -204,7 +217,17 @@ class ProjectCategory < ActiveRecord::Base
|
|
204
217
|
belongs_to :account
|
205
218
|
end
|
206
219
|
|
207
|
-
|
208
220
|
class AllowedPlace < ActiveRecord::Base
|
209
221
|
multi_tenant :account
|
210
222
|
end
|
223
|
+
|
224
|
+
class Domain < ActiveRecord::Base
|
225
|
+
multi_tenant :account
|
226
|
+
has_many :pages
|
227
|
+
default_scope { where(deleted: false) }
|
228
|
+
end
|
229
|
+
|
230
|
+
class Page < ActiveRecord::Base
|
231
|
+
multi_tenant :account
|
232
|
+
belongs_to :domain
|
233
|
+
end
|
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: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Citus Data
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: request_store
|
@@ -156,12 +156,12 @@ executables: []
|
|
156
156
|
extensions: []
|
157
157
|
extra_rdoc_files: []
|
158
158
|
files:
|
159
|
+
- ".github/workflows/CI.yml"
|
159
160
|
- ".gitignore"
|
160
|
-
- ".
|
161
|
+
- ".rspec"
|
161
162
|
- Appraisals
|
162
163
|
- CHANGELOG.md
|
163
164
|
- Gemfile
|
164
|
-
- Gemfile.lock
|
165
165
|
- LICENSE
|
166
166
|
- README.md
|
167
167
|
- Rakefile
|
@@ -169,17 +169,13 @@ files:
|
|
169
169
|
- docker-compose.yml
|
170
170
|
- gemfiles/.bundle/config
|
171
171
|
- gemfiles/active_record_5.2.gemfile
|
172
|
-
- gemfiles/active_record_5.2.gemfile.lock
|
173
172
|
- gemfiles/active_record_6.0.gemfile
|
174
|
-
- gemfiles/active_record_6.0.gemfile.lock
|
175
173
|
- gemfiles/active_record_6.1.gemfile
|
176
|
-
- gemfiles/
|
174
|
+
- gemfiles/active_record_7.0.gemfile
|
177
175
|
- gemfiles/rails_5.2.gemfile
|
178
|
-
- gemfiles/rails_5.2.gemfile.lock
|
179
176
|
- gemfiles/rails_6.0.gemfile
|
180
|
-
- gemfiles/rails_6.0.gemfile.lock
|
181
177
|
- gemfiles/rails_6.1.gemfile
|
182
|
-
- gemfiles/
|
178
|
+
- gemfiles/rails_7.0.gemfile
|
183
179
|
- lib/activerecord-multi-tenant.rb
|
184
180
|
- lib/activerecord-multi-tenant/arel_visitors_depth_first.rb
|
185
181
|
- lib/activerecord-multi-tenant/controller_extensions.rb
|
@@ -211,7 +207,7 @@ homepage: https://github.com/citusdata/activerecord-multi-tenant
|
|
211
207
|
licenses:
|
212
208
|
- MIT
|
213
209
|
metadata: {}
|
214
|
-
post_install_message:
|
210
|
+
post_install_message:
|
215
211
|
rdoc_options: []
|
216
212
|
require_paths:
|
217
213
|
- lib
|
@@ -226,8 +222,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
226
222
|
- !ruby/object:Gem::Version
|
227
223
|
version: '0'
|
228
224
|
requirements: []
|
229
|
-
rubygems_version: 3.
|
230
|
-
signing_key:
|
225
|
+
rubygems_version: 3.2.32
|
226
|
+
signing_key:
|
231
227
|
specification_version: 4
|
232
228
|
summary: ActiveRecord/Rails integration for multi-tenant databases, in particular
|
233
229
|
the Citus extension for PostgreSQL
|
data/.travis.yml
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
sudo: required
|
2
|
-
cache: bundler
|
3
|
-
|
4
|
-
language: ruby
|
5
|
-
|
6
|
-
rvm:
|
7
|
-
- 2.5.8
|
8
|
-
- 2.6.4
|
9
|
-
- 2.7.1
|
10
|
-
|
11
|
-
gemfile:
|
12
|
-
- gemfiles/rails_5.2.gemfile
|
13
|
-
- gemfiles/rails_6.0.gemfile
|
14
|
-
- gemfiles/rails_6.1.gemfile
|
15
|
-
- gemfiles/active_record_5.2.gemfile
|
16
|
-
- gemfiles/active_record_6.0.gemfile
|
17
|
-
- gemfiles/active_record_6.1.gemfile
|
18
|
-
|
19
|
-
env:
|
20
|
-
- PREPARED_STATEMENTS=0
|
21
|
-
- PREPARED_STATEMENTS=1
|
22
|
-
|
23
|
-
matrix:
|
24
|
-
fast_finish: true
|
25
|
-
|
26
|
-
services:
|
27
|
-
- docker
|
28
|
-
|
29
|
-
before_install:
|
30
|
-
- docker-compose up -d
|
31
|
-
- gem install bundler -v 2.1.4
|
32
|
-
|
33
|
-
script:
|
34
|
-
- bundle exec rake spec
|