mongoid-multitenancy 0.3.1 → 0.3.2
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 +8 -8
- data/Gemfile.lock +1 -1
- data/lib/mongoid/multitenancy.rb +1 -1
- data/lib/mongoid/multitenancy/document.rb +4 -5
- data/lib/mongoid/multitenancy/version.rb +1 -1
- data/lib/mongoid/validators/tenant_validator.rb +20 -0
- data/spec/immutable_spec.rb +34 -0
- data/spec/mandatory_spec.rb +82 -0
- data/spec/models/immutable.rb +15 -0
- data/spec/models/{page.rb → mandatory.rb} +3 -3
- data/spec/models/{article.rb → mutable.rb} +1 -1
- data/spec/models/optional.rb +15 -0
- data/spec/mongoid-multitenancy_spec.rb +1 -179
- data/spec/mutable_spec.rb +34 -0
- data/spec/optional_spec.rb +84 -0
- data/spec/spec_helper.rb +50 -0
- metadata +19 -7
- data/lib/mongoid/validators/immutable_validator.rb +0 -7
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZWQ3NzVkNzFkZGVlMDc3Y2Y5NTc1ZjI0MDhkNjA0YWRhNDIxMzMzNA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZDMzNmQyMmFmZmEyYTYwYWM5ZjA3NGI0NzkxOGI1MGIxYTU0NGM2OA==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YjJkOGZlZDVkODlhODE3ZWUwYzM2NjliZmRhNjRhMDYxYWI3NWJiZDE5YWU3
|
10
|
+
YWQ3ODg1OWUwNzRmYTg2OWMyMDA2OTY2MmNlZGE1Y2JkNWExNTM1NjI4YTc0
|
11
|
+
NWYwZGE3MmE2OGYxMzNhZWNkMjI2YzE0ZmE2NGMyNzAzMmZiYTg=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTBlZjk0OGFmM2Q4YjZhYjYyNjc3MTY0MmNiYTBjZjgxODNjM2Y3ZDA1NzMx
|
14
|
+
YmQ4MDkxOGU4MTgyMWM5ZWRiYThkMTUxMGJkYmQxOTY0OTYwMGM2ZWE3YTAy
|
15
|
+
ZDFmYzg3Y2FjOTAxMDZkZWMwNTg1NjExOWY5NjFlZjc2NzJmNDg=
|
data/Gemfile.lock
CHANGED
data/lib/mongoid/multitenancy.rb
CHANGED
@@ -16,13 +16,12 @@ module Mongoid
|
|
16
16
|
tenant_field = reflect_on_association(association).foreign_key
|
17
17
|
self.tenant_field = tenant_field
|
18
18
|
|
19
|
-
# Validates the
|
20
|
-
|
21
|
-
validates tenant_field, immutable: { field: tenant_field } if tenant_options[:immutable]
|
19
|
+
# Validates the tenant field
|
20
|
+
validates tenant_field, tenant: tenant_options
|
22
21
|
|
23
22
|
# Set the current_tenant on newly created objects
|
24
|
-
|
25
|
-
if Multitenancy.current_tenant
|
23
|
+
before_validation lambda { |m|
|
24
|
+
if Multitenancy.current_tenant and !tenant_options[:optional] and m.send(association.to_sym).nil?
|
26
25
|
m.send "#{association}=".to_sym, Multitenancy.current_tenant
|
27
26
|
end
|
28
27
|
true
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class TenantValidator < ActiveModel::EachValidator
|
2
|
+
def validate_each(object, attribute, value)
|
3
|
+
# Immutable Check
|
4
|
+
if options[:immutable]
|
5
|
+
if object.send(:attribute_changed?, attribute) and object.send(:attribute_was, attribute)
|
6
|
+
object.errors.add(attribute, 'is immutable and cannot be updated')
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
# Ownership check
|
11
|
+
if value and Mongoid::Multitenancy.current_tenant and value != Mongoid::Multitenancy.current_tenant.id
|
12
|
+
object.errors.add(attribute, "not authorized")
|
13
|
+
end
|
14
|
+
|
15
|
+
# Optional Check
|
16
|
+
if !options[:optional] and value.nil?
|
17
|
+
object.errors.add(attribute, 'is mandatory')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Immutable do
|
4
|
+
|
5
|
+
it_behaves_like "a tenantable model"
|
6
|
+
|
7
|
+
let(:client) { Account.create!(:name => "client") }
|
8
|
+
let(:another_client) { Account.create!(:name => "another client") }
|
9
|
+
|
10
|
+
describe "#valid?" do
|
11
|
+
before { Mongoid::Multitenancy.current_tenant = client; }
|
12
|
+
after { Mongoid::Multitenancy.current_tenant = nil }
|
13
|
+
|
14
|
+
let(:item) { Immutable.new(:title => "title X", :slug => "page-x") }
|
15
|
+
|
16
|
+
it_behaves_like "a tenant validator"
|
17
|
+
|
18
|
+
context "when the tenant has not changed" do
|
19
|
+
before { item.save! }
|
20
|
+
it 'should be valid' do
|
21
|
+
item.title = "title X (2)"
|
22
|
+
item.should be_valid
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when the tenant has changed" do
|
27
|
+
before { item.save!; Mongoid::Multitenancy.current_tenant = another_client }
|
28
|
+
it 'should not be valid' do
|
29
|
+
item.client = another_client
|
30
|
+
item.should_not be_valid
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mandatory do
|
4
|
+
|
5
|
+
it_behaves_like "a tenantable model"
|
6
|
+
|
7
|
+
let(:client) { Account.create!(:name => "client") }
|
8
|
+
let(:another_client) { Account.create!(:name => "another client") }
|
9
|
+
|
10
|
+
describe ".default_scope" do
|
11
|
+
before {
|
12
|
+
Mongoid::Multitenancy.with_tenant(client) { @itemX = Mandatory.create!(:title => "title X", :slug => "article-x") }
|
13
|
+
Mongoid::Multitenancy.with_tenant(another_client) { @itemY = Mandatory.create!(:title => "title Y", :slug => "article-y") }
|
14
|
+
}
|
15
|
+
|
16
|
+
context "with a current tenant" do
|
17
|
+
before { Mongoid::Multitenancy.current_tenant = another_client }
|
18
|
+
after { Mongoid::Multitenancy.current_tenant = nil }
|
19
|
+
|
20
|
+
it "should filter on the current tenant" do
|
21
|
+
Mandatory.all.to_a.should =~ [@itemY]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "without a current tenant" do
|
26
|
+
before { Mongoid::Multitenancy.current_tenant = nil }
|
27
|
+
|
28
|
+
it "should not filter on any tenant" do
|
29
|
+
Mandatory.all.to_a.should =~ [@itemX, @itemY]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#delete_all" do
|
35
|
+
before {
|
36
|
+
Mongoid::Multitenancy.with_tenant(client) { @itemX = Mandatory.create!(:title => "title X", :slug => "article-x") }
|
37
|
+
Mongoid::Multitenancy.with_tenant(another_client) { @itemY = Mandatory.create!(:title => "title Y", :slug => "article-y") }
|
38
|
+
}
|
39
|
+
|
40
|
+
context "with a current tenant" do
|
41
|
+
it "should only delete the current tenant" do
|
42
|
+
Mongoid::Multitenancy.with_tenant(another_client) { Mandatory.delete_all }
|
43
|
+
Mandatory.all.to_a.should =~ [@itemX]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "without a current tenant" do
|
48
|
+
it "should delete all the items" do
|
49
|
+
Mandatory.delete_all
|
50
|
+
Mandatory.all.to_a.should be_empty
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#valid?" do
|
56
|
+
after { Mongoid::Multitenancy.current_tenant = nil }
|
57
|
+
|
58
|
+
let(:item) { Mandatory.new(:title => "title X", :slug => "page-x") }
|
59
|
+
|
60
|
+
it_behaves_like "a tenant validator"
|
61
|
+
|
62
|
+
context "with a current tenant" do
|
63
|
+
before { Mongoid::Multitenancy.current_tenant = client }
|
64
|
+
|
65
|
+
it "should set the client field" do
|
66
|
+
item.valid?
|
67
|
+
item.client.should eq client
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "without a current tenant" do
|
72
|
+
it "should not set the client field" do
|
73
|
+
item.valid?
|
74
|
+
item.client.should be_nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should be invalid" do
|
78
|
+
item.should_not be_valid
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Immutable
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::Multitenancy::Document
|
4
|
+
|
5
|
+
tenant(:client, :class_name => 'Account', :immutable => true)
|
6
|
+
|
7
|
+
field :slug, :type => String
|
8
|
+
field :title, :type => String
|
9
|
+
|
10
|
+
validates_uniqueness_of :slug
|
11
|
+
validates_presence_of :slug
|
12
|
+
validates_presence_of :title
|
13
|
+
|
14
|
+
index({ :title => 1 })
|
15
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
class
|
1
|
+
class Mandatory
|
2
2
|
include Mongoid::Document
|
3
3
|
include Mongoid::Multitenancy::Document
|
4
4
|
|
5
|
-
tenant(:client, :class_name => 'Account'
|
5
|
+
tenant(:client, :class_name => 'Account')
|
6
6
|
|
7
7
|
field :slug, :type => String
|
8
8
|
field :title, :type => String
|
@@ -12,4 +12,4 @@ class Page
|
|
12
12
|
validates_presence_of :title
|
13
13
|
|
14
14
|
index({ :title => 1 })
|
15
|
-
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Optional
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::Multitenancy::Document
|
4
|
+
|
5
|
+
tenant(:client, :class_name => 'Account', :optional => true)
|
6
|
+
|
7
|
+
field :slug, :type => String
|
8
|
+
field :title, :type => String
|
9
|
+
|
10
|
+
validates_uniqueness_of :slug
|
11
|
+
validates_presence_of :slug
|
12
|
+
validates_presence_of :title
|
13
|
+
|
14
|
+
index({ :title => 1 })
|
15
|
+
end
|
@@ -19,182 +19,4 @@ describe Mongoid::Multitenancy do
|
|
19
19
|
Mongoid::Multitenancy.current_tenant.should == client
|
20
20
|
end
|
21
21
|
end
|
22
|
-
end
|
23
|
-
|
24
|
-
shared_examples_for "a tenantable model" do
|
25
|
-
|
26
|
-
it { should belong_to(:client) }
|
27
|
-
it { should validate_uniqueness_of(:slug).scoped_to(:client_id) }
|
28
|
-
it { should have_index_for(:client_id => 1, :title => 1) }
|
29
|
-
|
30
|
-
let(:client) { Account.create!(:name => "client") }
|
31
|
-
let(:another_client) { Account.create!(:name => "another client") }
|
32
|
-
|
33
|
-
describe ".initialize" do
|
34
|
-
before { Mongoid::Multitenancy.current_tenant = client }
|
35
|
-
after { Mongoid::Multitenancy.current_tenant = nil }
|
36
|
-
|
37
|
-
it "should set the client field" do
|
38
|
-
described_class.new.client.should eq client
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
describe Page do
|
45
|
-
|
46
|
-
it_behaves_like "a tenantable model"
|
47
|
-
|
48
|
-
it { should_not validate_presence_of(:client_id) }
|
49
|
-
|
50
|
-
let(:client) { Account.create!(:name => "client") }
|
51
|
-
let(:another_client) { Account.create!(:name => "another client") }
|
52
|
-
|
53
|
-
describe ".default_scope" do
|
54
|
-
before {
|
55
|
-
@itemC = described_class.create!(:title => "title C", :slug => "article-c")
|
56
|
-
Mongoid::Multitenancy.with_tenant(client) { @itemX = described_class.create!(:title => "title X", :slug => "article-x") }
|
57
|
-
Mongoid::Multitenancy.with_tenant(another_client) { @itemY = described_class.create!(:title => "title Y", :slug => "article-y") }
|
58
|
-
}
|
59
|
-
|
60
|
-
context "with a current tenant" do
|
61
|
-
before { Mongoid::Multitenancy.current_tenant = another_client }
|
62
|
-
after { Mongoid::Multitenancy.current_tenant = nil }
|
63
|
-
|
64
|
-
it "should filter on the current tenant / free-tenant items" do
|
65
|
-
described_class.all.to_a.should =~ [@itemY, @itemC]
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
context "without a current tenant" do
|
70
|
-
before { Mongoid::Multitenancy.current_tenant = nil }
|
71
|
-
|
72
|
-
it "should not filter on any tenant" do
|
73
|
-
described_class.all.to_a.should =~ [@itemC, @itemX, @itemY]
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
describe "#delete_all" do
|
79
|
-
before {
|
80
|
-
@itemC = described_class.create!(:title => "title C", :slug => "article-c")
|
81
|
-
Mongoid::Multitenancy.with_tenant(client) { @itemX = described_class.create!(:title => "title X", :slug => "article-x") }
|
82
|
-
Mongoid::Multitenancy.with_tenant(another_client) { @itemY = described_class.create!(:title => "title Y", :slug => "article-y") }
|
83
|
-
}
|
84
|
-
|
85
|
-
context "with a current tenant" do
|
86
|
-
it "should only delete the current tenant / free-tenant items" do
|
87
|
-
Mongoid::Multitenancy.with_tenant(another_client) { described_class.delete_all }
|
88
|
-
described_class.all.to_a.should =~ [@itemX]
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context "without a current tenant" do
|
93
|
-
it "should delete all the pages" do
|
94
|
-
described_class.delete_all
|
95
|
-
described_class.all.to_a.should be_empty
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
describe Article do
|
103
|
-
|
104
|
-
it_behaves_like "a tenantable model"
|
105
|
-
|
106
|
-
it { should validate_presence_of(:client_id) }
|
107
|
-
|
108
|
-
let(:client) { Account.create!(:name => "client") }
|
109
|
-
let(:another_client) { Account.create!(:name => "another client") }
|
110
|
-
|
111
|
-
describe ".default_scope" do
|
112
|
-
before {
|
113
|
-
Mongoid::Multitenancy.with_tenant(client) { @itemX = described_class.create!(:title => "title X", :slug => "article-x") }
|
114
|
-
Mongoid::Multitenancy.with_tenant(another_client) { @itemY = described_class.create!(:title => "title Y", :slug => "article-y") }
|
115
|
-
}
|
116
|
-
|
117
|
-
context "with a current tenant" do
|
118
|
-
before { Mongoid::Multitenancy.current_tenant = another_client }
|
119
|
-
after { Mongoid::Multitenancy.current_tenant = nil }
|
120
|
-
|
121
|
-
it "should filter on the current tenant" do
|
122
|
-
described_class.all.to_a.should =~ [@itemY]
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
context "without a current tenant" do
|
127
|
-
before { Mongoid::Multitenancy.current_tenant = nil }
|
128
|
-
|
129
|
-
it "should not filter on any tenant" do
|
130
|
-
described_class.all.to_a.should =~ [@itemX, @itemY]
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
describe "#valid?" do
|
136
|
-
before { Mongoid::Multitenancy.current_tenant = client }
|
137
|
-
after { Mongoid::Multitenancy.current_tenant = nil }
|
138
|
-
|
139
|
-
context "with :immutable" do
|
140
|
-
let(:item) { Page.create!(:title => "title X", :slug => "article-x") }
|
141
|
-
|
142
|
-
context "when the tenant has not changed" do
|
143
|
-
it 'should be valid' do
|
144
|
-
item.title = "title X (2)"
|
145
|
-
item.should be_valid
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
context "when the tenant has changed" do
|
150
|
-
it 'should be invalid' do
|
151
|
-
item.title = "title X (2)"
|
152
|
-
item.client = another_client
|
153
|
-
item.should_not be_valid
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
context "without :immutable" do
|
159
|
-
let(:item) { Article.create!(:title => "title X", :slug => "article-x") }
|
160
|
-
|
161
|
-
context "when the tenant has not changed" do
|
162
|
-
it 'should be valid' do
|
163
|
-
item.title = "title X (2)"
|
164
|
-
item.should be_valid
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
context "when the tenant has changed" do
|
169
|
-
it 'should be valid' do
|
170
|
-
item.title = "title X (2)"
|
171
|
-
item.client = another_client
|
172
|
-
item.should be_valid
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
end
|
178
|
-
|
179
|
-
describe "#delete_all" do
|
180
|
-
before {
|
181
|
-
Mongoid::Multitenancy.with_tenant(client) { @itemX = described_class.create!(:title => "title X", :slug => "article-x") }
|
182
|
-
Mongoid::Multitenancy.with_tenant(another_client) { @itemY = described_class.create!(:title => "title Y", :slug => "article-y") }
|
183
|
-
}
|
184
|
-
|
185
|
-
context "with a current tenant" do
|
186
|
-
it "should only delete the current tenant articles" do
|
187
|
-
Mongoid::Multitenancy.with_tenant(another_client) { described_class.delete_all }
|
188
|
-
described_class.all.to_a.should =~ [@itemX]
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
context "without a current tenant" do
|
193
|
-
it "should delete all the articles" do
|
194
|
-
described_class.delete_all
|
195
|
-
described_class.all.to_a.should be_empty
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
end
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mutable do
|
4
|
+
|
5
|
+
it_behaves_like "a tenantable model"
|
6
|
+
|
7
|
+
let(:client) { Account.create!(:name => "client") }
|
8
|
+
let(:another_client) { Account.create!(:name => "another client") }
|
9
|
+
|
10
|
+
describe "#valid?" do
|
11
|
+
before { Mongoid::Multitenancy.current_tenant = client; }
|
12
|
+
after { Mongoid::Multitenancy.current_tenant = nil }
|
13
|
+
|
14
|
+
let(:item) { Mutable.new(:title => "title X", :slug => "page-x") }
|
15
|
+
|
16
|
+
it_behaves_like "a tenant validator"
|
17
|
+
|
18
|
+
context "when the tenant has not changed" do
|
19
|
+
before { item.save! }
|
20
|
+
it 'should be valid' do
|
21
|
+
item.title = "title X (2)"
|
22
|
+
item.should be_valid
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when the tenant has changed" do
|
27
|
+
before { item.save!; Mongoid::Multitenancy.current_tenant = another_client }
|
28
|
+
it 'should be valid' do
|
29
|
+
item.client = another_client
|
30
|
+
item.should be_valid
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Optional do
|
4
|
+
|
5
|
+
it_behaves_like "a tenantable model"
|
6
|
+
|
7
|
+
let(:client) { Account.create!(:name => "client") }
|
8
|
+
let(:another_client) { Account.create!(:name => "another client") }
|
9
|
+
|
10
|
+
describe ".default_scope" do
|
11
|
+
before {
|
12
|
+
@itemC = Optional.create!(:title => "title C", :slug => "article-c")
|
13
|
+
Mongoid::Multitenancy.with_tenant(client) { @itemX = Optional.create!(:title => "title X", :slug => "article-x", :client => client) }
|
14
|
+
Mongoid::Multitenancy.with_tenant(another_client) { @itemY = Optional.create!(:title => "title Y", :slug => "article-y", :client => another_client) }
|
15
|
+
}
|
16
|
+
|
17
|
+
context "with a current tenant" do
|
18
|
+
before { Mongoid::Multitenancy.current_tenant = another_client }
|
19
|
+
after { Mongoid::Multitenancy.current_tenant = nil }
|
20
|
+
|
21
|
+
it "should filter on the current tenant / free-tenant items" do
|
22
|
+
Optional.all.to_a.should =~ [@itemY, @itemC]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "without a current tenant" do
|
27
|
+
before { Mongoid::Multitenancy.current_tenant = nil }
|
28
|
+
|
29
|
+
it "should not filter on any tenant" do
|
30
|
+
Optional.all.to_a.should =~ [@itemC, @itemX, @itemY]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#delete_all" do
|
36
|
+
before {
|
37
|
+
@itemC = Optional.create!(:title => "title C", :slug => "article-c")
|
38
|
+
Mongoid::Multitenancy.with_tenant(client) { @itemX = Optional.create!(:title => "title X", :slug => "article-x", :client => client) }
|
39
|
+
Mongoid::Multitenancy.with_tenant(another_client) { @itemY = Optional.create!(:title => "title Y", :slug => "article-y", :client => another_client) }
|
40
|
+
}
|
41
|
+
|
42
|
+
context "with a current tenant" do
|
43
|
+
it "should only delete the current tenant / free-tenant items" do
|
44
|
+
Mongoid::Multitenancy.with_tenant(another_client) { Optional.delete_all }
|
45
|
+
Optional.all.to_a.should =~ [@itemX]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "without a current tenant" do
|
50
|
+
it "should delete all the pages" do
|
51
|
+
Optional.delete_all
|
52
|
+
Optional.all.to_a.should be_empty
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#valid?" do
|
58
|
+
after { Mongoid::Multitenancy.current_tenant = nil }
|
59
|
+
|
60
|
+
let(:item) { Optional.new(:title => "title X", :slug => "page-x") }
|
61
|
+
|
62
|
+
it_behaves_like "a tenant validator"
|
63
|
+
|
64
|
+
context "with a current tenant" do
|
65
|
+
before { Mongoid::Multitenancy.current_tenant = client }
|
66
|
+
|
67
|
+
it "should not set the client field" do
|
68
|
+
item.valid?
|
69
|
+
item.client.should be_nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "without a current tenant" do
|
74
|
+
it "should not set the client field" do
|
75
|
+
item.valid?
|
76
|
+
item.client.should be_nil
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should be valid" do
|
80
|
+
item.should be_valid
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -36,3 +36,53 @@ RSpec.configure do |config|
|
|
36
36
|
DatabaseCleaner.clean
|
37
37
|
end
|
38
38
|
end
|
39
|
+
|
40
|
+
shared_examples_for "a tenantable model" do
|
41
|
+
|
42
|
+
it { should belong_to(:client) }
|
43
|
+
it { should validate_uniqueness_of(:slug).scoped_to(:client_id) }
|
44
|
+
it { should have_index_for(:client_id => 1, :title => 1) }
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
shared_examples_for "a tenant validator" do
|
49
|
+
context "within a client context" do
|
50
|
+
before { Mongoid::Multitenancy.current_tenant = client }
|
51
|
+
|
52
|
+
context "with the client id" do
|
53
|
+
before { item.client = client }
|
54
|
+
|
55
|
+
it "should be valid" do
|
56
|
+
item.should be_valid
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "with another client id" do
|
61
|
+
before { item.client = another_client }
|
62
|
+
|
63
|
+
it "should be invalid" do
|
64
|
+
item.should_not be_valid
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "without a client context" do
|
70
|
+
before { Mongoid::Multitenancy.current_tenant = nil }
|
71
|
+
|
72
|
+
context "with the client id" do
|
73
|
+
before { item.client = client }
|
74
|
+
|
75
|
+
it "should be valid" do
|
76
|
+
item.should be_valid
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "with another client id" do
|
81
|
+
before { item.client = another_client }
|
82
|
+
|
83
|
+
it "should be valid" do
|
84
|
+
item.should be_valid
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid-multitenancy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aymeric Brisse
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-06-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mongoid
|
@@ -126,12 +126,18 @@ files:
|
|
126
126
|
- lib/mongoid/multitenancy.rb
|
127
127
|
- lib/mongoid/multitenancy/document.rb
|
128
128
|
- lib/mongoid/multitenancy/version.rb
|
129
|
-
- lib/mongoid/validators/
|
129
|
+
- lib/mongoid/validators/tenant_validator.rb
|
130
130
|
- mongoid-multitenancy.gemspec
|
131
|
+
- spec/immutable_spec.rb
|
132
|
+
- spec/mandatory_spec.rb
|
131
133
|
- spec/models/account.rb
|
132
|
-
- spec/models/
|
133
|
-
- spec/models/
|
134
|
+
- spec/models/immutable.rb
|
135
|
+
- spec/models/mandatory.rb
|
136
|
+
- spec/models/mutable.rb
|
137
|
+
- spec/models/optional.rb
|
134
138
|
- spec/mongoid-multitenancy_spec.rb
|
139
|
+
- spec/mutable_spec.rb
|
140
|
+
- spec/optional_spec.rb
|
135
141
|
- spec/spec_helper.rb
|
136
142
|
homepage: https://github.com/PerfectMemory/mongoid-multitenancy
|
137
143
|
licenses: []
|
@@ -157,9 +163,15 @@ signing_key:
|
|
157
163
|
specification_version: 4
|
158
164
|
summary: Support of a multi-tenant database with Mongoid
|
159
165
|
test_files:
|
166
|
+
- spec/immutable_spec.rb
|
167
|
+
- spec/mandatory_spec.rb
|
160
168
|
- spec/models/account.rb
|
161
|
-
- spec/models/
|
162
|
-
- spec/models/
|
169
|
+
- spec/models/immutable.rb
|
170
|
+
- spec/models/mandatory.rb
|
171
|
+
- spec/models/mutable.rb
|
172
|
+
- spec/models/optional.rb
|
163
173
|
- spec/mongoid-multitenancy_spec.rb
|
174
|
+
- spec/mutable_spec.rb
|
175
|
+
- spec/optional_spec.rb
|
164
176
|
- spec/spec_helper.rb
|
165
177
|
has_rdoc:
|
@@ -1,7 +0,0 @@
|
|
1
|
-
class ImmutableValidator < ActiveModel::EachValidator
|
2
|
-
def validate_each(object, attribute, value)
|
3
|
-
if object.send(:attribute_changed?, options[:field]) and object.send(:attribute_was, options[:field])
|
4
|
-
object.errors.add(options[:field], 'is immutable and cannot be updated') and false
|
5
|
-
end
|
6
|
-
end
|
7
|
-
end
|