acts_as_tenant 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG.md +5 -0
- data/README.md +19 -13
- data/lib/acts_as_tenant/model_extensions.rb +40 -25
- data/lib/acts_as_tenant/version.rb +1 -1
- data/spec/acts_as_tenant/model_extensions_spec.rb +104 -63
- data/spec/acts_as_tenant/tenant_by_filter_spec.rb +2 -2
- data/spec/acts_as_tenant/tenant_by_subdomain_spec.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZDM3YTQ2MDk4YjRjZGRkNDlkMjVlNjVhYmE4MDhlYTZlZDcxY2JlNQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YjIxMTk0YzRmMDg1MmZhNTk2ZDRjMjZiODE4YTA5ZTA1MDgyMzc1OA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZjI5MTQzMDEzZTJhYjBiYWI1NjQyOTdhNjhkZTViZGRhZGVkYTVlMWE2MjFk
|
10
|
+
NzE2YzMzMmY1YTJhZGUwN2E3MzgzOWQ1M2EwZjFlZWZjMzQ4MTAwMjFmMWUx
|
11
|
+
NGIzYmVhYTAwNGRhZDUzZWQyMzkzMDIyOTJlM2YxZWY5OTM0OTg=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NzY1MDRhMzUxYzgxNzRhYzAxZGYzOTk5OTJiMGUzMzU2ODUwMGMwNTM0MmJh
|
14
|
+
M2FhOWQxMmExNzYyMjM0NThiZDY4MDM0ZDVjOWIwMDI2NzFhMDQ4YzdhNmU1
|
15
|
+
ZjhiMzY1MGZkODJmY2E2MjlmNjAwNzkxMTdmNzlkMTljM2IxM2Y=
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
+
0.3.3
|
2
|
+
-----
|
3
|
+
* Support user defined foreign keys on scoped models
|
4
|
+
|
1
5
|
0.3.2
|
2
6
|
-----
|
3
7
|
* correctly support nested models with has_many :through (thx dexion)
|
4
8
|
* Support 'www.subdomain.example.com' (thx wtfiwtz)
|
9
|
+
* Support user defined foreign keys on scoped models
|
5
10
|
* Support setting `tenant_id` on scoped models if the `tenant_id` is nil (thx Matt Wilson)
|
6
11
|
|
7
12
|
0.3.1
|
data/README.md
CHANGED
@@ -21,14 +21,14 @@ Installation
|
|
21
21
|
acts_as_tenant will only work on Rails 3.1 and up. This is due to changes made to the handling of default_scope, an essential pillar of the gem.
|
22
22
|
|
23
23
|
To use it, add it to your Gemfile:
|
24
|
-
|
24
|
+
|
25
25
|
gem 'acts_as_tenant'
|
26
|
-
|
26
|
+
|
27
27
|
Getting started
|
28
28
|
===============
|
29
29
|
There are two steps in adding multi-tenancy to your app with acts_as_tenant:
|
30
30
|
|
31
|
-
1. setting the current tenant and
|
31
|
+
1. setting the current tenant and
|
32
32
|
2. scoping your models.
|
33
33
|
|
34
34
|
Setting the current tenant
|
@@ -48,7 +48,7 @@ This tells acts_as_tenant to use the current subdomain to identify the current t
|
|
48
48
|
class ApplicationController < ActionController::Base
|
49
49
|
set_current_tenant_through_filter
|
50
50
|
before_filter :your_method_that_finds_the_current_tenant
|
51
|
-
|
51
|
+
|
52
52
|
def your_method_that_finds_the_current_tenant
|
53
53
|
current_account = Account.find_it
|
54
54
|
set_current_tenant(current_account)
|
@@ -83,26 +83,26 @@ Scoping your models
|
|
83
83
|
class User < ActiveRecord::Base
|
84
84
|
acts_as_tenant(:account)
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
acts_as_tenant requires each scoped model to have a column in its schema linking it to a tenant. Adding acts_as_tenant to your model declaration will scope that model to the current tenant **BUT ONLY if a current tenant has been set**.
|
88
88
|
|
89
89
|
Some examples to illustrate this behavior:
|
90
90
|
|
91
91
|
# This manually sets the current tenant for testing purposes. In your app this is handled by the gem.
|
92
|
-
ActsAsTenant.current_tenant = Account.find(3)
|
93
|
-
|
94
|
-
# All searches are scoped by the tenant, the following searches will only return objects
|
92
|
+
ActsAsTenant.current_tenant = Account.find(3)
|
93
|
+
|
94
|
+
# All searches are scoped by the tenant, the following searches will only return objects
|
95
95
|
# where account_id == 3
|
96
96
|
Project.all => # all projects with account_id => 3
|
97
97
|
Project.tasks.all # => all tasks with account_id => 3
|
98
|
-
|
98
|
+
|
99
99
|
# New objects are scoped to the current tenant
|
100
100
|
@project = Project.new(:name => 'big project') # => <#Project id: nil, name: 'big project', :account_id: 3>
|
101
|
-
|
101
|
+
|
102
102
|
# It will not allow the creation of objects outside the current_tenant scope
|
103
103
|
@project.account_id = 2
|
104
104
|
@project.save # => false
|
105
|
-
|
105
|
+
|
106
106
|
# It will not allow association with objects outside the current tenant scope
|
107
107
|
# Assuming the Project with ID: 2 does not belong to Account with ID: 3
|
108
108
|
@task = Task.new # => <#Task id: nil, name: nil, project_id: nil, :account_id: 3>
|
@@ -117,6 +117,12 @@ If you need to validate for uniqueness, chances are that you want to scope this
|
|
117
117
|
|
118
118
|
All options available to Rails' own `validates_uniqueness_of` are also available to this method.
|
119
119
|
|
120
|
+
**Custom foreign_key**
|
121
|
+
|
122
|
+
You can explicitely specifiy a foreign_key for AaT to use should the key differ from the default:
|
123
|
+
|
124
|
+
acts_as_tenant(:account, :foreign_key => 'accountID) # by default AaT expects account_id
|
125
|
+
|
120
126
|
Configuration options
|
121
127
|
---------------------
|
122
128
|
An initializer can be created to control (currently one) option in ActsAsTenant. Defaults
|
@@ -136,7 +142,7 @@ Whenever you set the `current_tenant` in your tests, either through integration
|
|
136
142
|
|
137
143
|
To Do
|
138
144
|
-----
|
139
|
-
*
|
145
|
+
* ...
|
140
146
|
|
141
147
|
Bug reports & suggested improvements
|
142
148
|
------------------------------------
|
@@ -148,7 +154,7 @@ If you want to contribute, fork the project, code your improvements and make a p
|
|
148
154
|
|
149
155
|
Author & Credits
|
150
156
|
----------------
|
151
|
-
acts_as_tenant is written by Erwin Matthijssen.
|
157
|
+
acts_as_tenant is written by Erwin Matthijssen.
|
152
158
|
Erwin is currently busy developing [Roll Call](http://www.rollcallapp.com/ "Roll Call App").
|
153
159
|
|
154
160
|
This gem was inspired by Ryan Sonnek's [Multitenant](https://github.com/wireframe/multitenant) gem and its use of default_scope.
|
@@ -1,18 +1,18 @@
|
|
1
1
|
module ActsAsTenant
|
2
2
|
@@tenant_klass = nil
|
3
|
-
|
3
|
+
|
4
4
|
def self.set_tenant_klass(klass)
|
5
5
|
@@tenant_klass = klass
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
def self.tenant_klass
|
9
9
|
@@tenant_klass
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def self.fkey
|
13
13
|
"#{@@tenant_klass.to_s}_id"
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def self.current_tenant=(tenant)
|
17
17
|
RequestStore.store[:current_tenant] = tenant
|
18
18
|
end
|
@@ -34,22 +34,30 @@ module ActsAsTenant
|
|
34
34
|
ensure
|
35
35
|
self.current_tenant = old_tenant
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
module ModelExtensions
|
39
39
|
def self.included(base)
|
40
40
|
base.extend(ClassMethods)
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
module ClassMethods
|
44
|
-
def acts_as_tenant(
|
45
|
-
|
46
|
-
ActsAsTenant.set_tenant_klass(
|
47
|
-
|
44
|
+
def acts_as_tenant(tenant = :account, options = {})
|
45
|
+
|
46
|
+
ActsAsTenant.set_tenant_klass(tenant)
|
47
|
+
|
48
|
+
unless options[:foreign_key].nil?
|
49
|
+
fkey = options[:foreign_key]
|
50
|
+
belongs_to tenant, :foreign_key => fkey
|
51
|
+
else
|
52
|
+
fkey = ActsAsTenant.fkey
|
53
|
+
belongs_to tenant
|
54
|
+
end
|
55
|
+
|
48
56
|
default_scope lambda {
|
49
57
|
if ActsAsTenant.configuration.require_tenant && ActsAsTenant.current_tenant.nil?
|
50
58
|
raise ActsAsTenant::Errors::NoTenantSet
|
51
59
|
end
|
52
|
-
where("#{self.table_name}.#{
|
60
|
+
where("#{self.table_name}.#{fkey} = ?", ActsAsTenant.current_tenant.id) if ActsAsTenant.current_tenant
|
53
61
|
}
|
54
62
|
|
55
63
|
# Add the following validations to the receiving model:
|
@@ -58,47 +66,54 @@ module ActsAsTenant
|
|
58
66
|
#
|
59
67
|
before_validation Proc.new {|m|
|
60
68
|
if ActsAsTenant.current_tenant
|
61
|
-
m.send "#{
|
69
|
+
m.send "#{fkey}=".to_sym, ActsAsTenant.current_tenant.id
|
62
70
|
end
|
63
71
|
}, :on => :create
|
64
|
-
|
72
|
+
|
65
73
|
reflect_on_all_associations.each do |a|
|
66
|
-
unless a == reflect_on_association(
|
74
|
+
unless a == reflect_on_association(tenant) || a.macro != :belongs_to || a.options[:polymorphic]
|
67
75
|
association_class = a.options[:class_name].nil? ? a.name.to_s.classify.constantize : a.options[:class_name].constantize
|
68
76
|
validates_each a.foreign_key.to_sym do |record, attr, value|
|
69
77
|
record.errors.add attr, "association is invalid [ActsAsTenant]" unless value.nil? || association_class.where(:id => value).present?
|
70
78
|
end
|
71
79
|
end
|
72
80
|
end
|
73
|
-
|
81
|
+
|
74
82
|
# Dynamically generate the following methods:
|
75
83
|
# - Rewrite the accessors to make tenant immutable
|
84
|
+
# - Add an override to prevent unnecessary db hits
|
76
85
|
# - Add a helper method to verify if a model has been scoped by AaT
|
77
86
|
#
|
78
|
-
define_method "#{
|
79
|
-
raise ActsAsTenant::Errors::TenantIsImmutable unless new_record? || send(
|
80
|
-
write_attribute("#{
|
87
|
+
define_method "#{fkey}=" do |integer|
|
88
|
+
raise ActsAsTenant::Errors::TenantIsImmutable unless new_record? || send(fkey).nil?
|
89
|
+
write_attribute("#{fkey}", integer)
|
81
90
|
end
|
82
91
|
|
83
92
|
define_method "#{ActsAsTenant.tenant_klass.to_s}=" do |model|
|
84
|
-
raise ActsAsTenant::Errors::TenantIsImmutable unless new_record? || send(
|
93
|
+
raise ActsAsTenant::Errors::TenantIsImmutable unless new_record? || send(fkey).nil?
|
85
94
|
super(model)
|
86
95
|
end
|
87
|
-
|
96
|
+
|
97
|
+
define_method "#{ActsAsTenant.tenant_klass.to_s}" do
|
98
|
+
return ActsAsTenant.current_tenant if send(fkey) == ActsAsTenant.current_tenant.id
|
99
|
+
super()
|
100
|
+
end
|
101
|
+
|
88
102
|
def scoped_by_tenant?
|
89
103
|
true
|
90
104
|
end
|
91
105
|
end
|
92
|
-
|
106
|
+
|
93
107
|
def validates_uniqueness_to_tenant(fields, args ={})
|
94
108
|
raise ActsAsTenant::Errors::ModelNotScopedByTenant unless respond_to?(:scoped_by_tenant?)
|
95
|
-
|
109
|
+
fkey = reflect_on_association(ActsAsTenant.tenant_klass).foreign_key
|
110
|
+
#tenant_id = lambda { "#{ActsAsTenant.fkey}"}.call
|
96
111
|
if args[:scope]
|
97
|
-
args[:scope] = Array(args[:scope]) <<
|
112
|
+
args[:scope] = Array(args[:scope]) << fkey
|
98
113
|
else
|
99
|
-
args[:scope] =
|
114
|
+
args[:scope] = fkey
|
100
115
|
end
|
101
|
-
|
116
|
+
|
102
117
|
validates_uniqueness_of(fields, args)
|
103
118
|
end
|
104
119
|
end
|
@@ -29,17 +29,28 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
29
29
|
t.column :name, :string
|
30
30
|
end
|
31
31
|
|
32
|
-
create_table :
|
32
|
+
create_table :unscoped_models, :force => true do |t|
|
33
33
|
t.column :name, :string
|
34
34
|
end
|
35
35
|
|
36
|
-
create_table :
|
36
|
+
create_table :aliased_tasks, :force => true do |t|
|
37
37
|
t.column :name, :string
|
38
|
-
t.column :
|
39
|
-
t.column :something_else, :integer
|
38
|
+
t.column :project_alias_id, :integer
|
40
39
|
t.column :account_id, :integer
|
41
40
|
end
|
42
41
|
|
42
|
+
create_table :unique_tasks, :force => true do |t|
|
43
|
+
t.column :name, :string
|
44
|
+
t.column :user_defined_scope, :string
|
45
|
+
t.column :project_id, :integer
|
46
|
+
t.column :account_id, :integer
|
47
|
+
end
|
48
|
+
|
49
|
+
create_table :custom_foreign_key_tasks, :force => true do |t|
|
50
|
+
t.column :name, :string
|
51
|
+
t.column :accountID, :integer
|
52
|
+
end
|
53
|
+
|
43
54
|
end
|
44
55
|
|
45
56
|
# Setup the models
|
@@ -68,20 +79,31 @@ class Task < ActiveRecord::Base
|
|
68
79
|
validates_uniqueness_of :name
|
69
80
|
end
|
70
81
|
|
71
|
-
class
|
82
|
+
class UnscopedModel < ActiveRecord::Base
|
72
83
|
validates_uniqueness_of :name
|
73
84
|
end
|
74
85
|
|
75
|
-
class
|
76
|
-
acts_as_tenant
|
77
|
-
belongs_to :
|
78
|
-
|
86
|
+
class AliasedTask < ActiveRecord::Base
|
87
|
+
acts_as_tenant(:account)
|
88
|
+
belongs_to :project_alias, :class_name => "Project"
|
89
|
+
end
|
90
|
+
|
91
|
+
class UniqueTask < ActiveRecord::Base
|
92
|
+
acts_as_tenant(:account)
|
93
|
+
belongs_to :project
|
94
|
+
validates_uniqueness_to_tenant :name, scope: :user_defined_scope
|
95
|
+
end
|
96
|
+
|
97
|
+
class CustomForeignKeyTask < ActiveRecord::Base
|
98
|
+
acts_as_tenant(:account, :foreign_key => "accountID")
|
99
|
+
validates_uniqueness_to_tenant :name
|
79
100
|
end
|
80
101
|
|
81
102
|
# Start testing!
|
82
103
|
describe ActsAsTenant do
|
83
104
|
after { ActsAsTenant.current_tenant = nil }
|
84
105
|
|
106
|
+
# Setting and getting
|
85
107
|
describe 'Setting the current tenant' do
|
86
108
|
before { ActsAsTenant.current_tenant = :foo }
|
87
109
|
it { ActsAsTenant.current_tenant == :foo }
|
@@ -91,6 +113,36 @@ describe ActsAsTenant do
|
|
91
113
|
it {Project.respond_to?(:scoped_by_tenant?).should == true}
|
92
114
|
end
|
93
115
|
|
116
|
+
describe 'tenant_id should be immutable, if already set' do
|
117
|
+
before do
|
118
|
+
@account = Account.create!(:name => 'foo')
|
119
|
+
@project = @account.projects.create!(:name => 'bar')
|
120
|
+
end
|
121
|
+
|
122
|
+
it { lambda {@project.account_id = @account.id + 1}.should raise_error }
|
123
|
+
end
|
124
|
+
|
125
|
+
describe 'tenant_id should be mutable, if not already set' do
|
126
|
+
before do
|
127
|
+
@account = Account.create!(:name => 'foo')
|
128
|
+
@project = Project.create!(:name => 'bar')
|
129
|
+
end
|
130
|
+
|
131
|
+
it { @project.account_id.should be_nil }
|
132
|
+
it { lambda { @project.account = @account }.should_not raise_error }
|
133
|
+
end
|
134
|
+
|
135
|
+
describe 'Handles custom foreign_key on tenant model' do
|
136
|
+
before do
|
137
|
+
@account = Account.create!(:name => 'foo')
|
138
|
+
ActsAsTenant.current_tenant = @account
|
139
|
+
@custom_foreign_key_task = CustomForeignKeyTask.create!(:name => 'foo')
|
140
|
+
end
|
141
|
+
|
142
|
+
it { @custom_foreign_key_task.account.should == @account }
|
143
|
+
end
|
144
|
+
|
145
|
+
# Scoping models
|
94
146
|
describe 'Project.all should be scoped to the current tenant if set' do
|
95
147
|
before do
|
96
148
|
@account1 = Account.create!(:name => 'foo')
|
@@ -122,11 +174,12 @@ describe ActsAsTenant do
|
|
122
174
|
it { @projects.count.should == 2 }
|
123
175
|
end
|
124
176
|
|
177
|
+
# Associations
|
125
178
|
describe 'Associations should be correctly scoped by current tenant' do
|
126
179
|
before do
|
127
180
|
@account = Account.create!(:name => 'foo')
|
128
|
-
@project =
|
129
|
-
# the next line
|
181
|
+
@project = Project.create!(:name => 'foobar', :account => @account )
|
182
|
+
# the next line should normally be (nearly) impossible: a task assigned to a tenant project,
|
130
183
|
# but the task has no tenant assigned
|
131
184
|
@task1 = Task.create!(:name => 'no_tenant', :project => @project)
|
132
185
|
|
@@ -144,6 +197,30 @@ describe ActsAsTenant do
|
|
144
197
|
end
|
145
198
|
end
|
146
199
|
|
200
|
+
describe 'Associations can only be made with in-scope objects' do
|
201
|
+
before do
|
202
|
+
@account = Account.create!(:name => 'foo')
|
203
|
+
@project1 = Project.create!(:name => 'inaccessible_project', :account_id => @account.id + 1)
|
204
|
+
|
205
|
+
ActsAsTenant.current_tenant = @account
|
206
|
+
@project2 = Project.create!(:name => 'accessible_project')
|
207
|
+
@task = @project2.tasks.create!(:name => 'bar')
|
208
|
+
end
|
209
|
+
|
210
|
+
it { @task.update_attributes(:project_id => @project1.id).should == false }
|
211
|
+
end
|
212
|
+
|
213
|
+
describe "Create and save an AaT-enabled child without it having a parent" do
|
214
|
+
@account = Account.create!(:name => 'baz')
|
215
|
+
ActsAsTenant.current_tenant = @account
|
216
|
+
Task.create(:name => 'bar').valid?.should == true
|
217
|
+
end
|
218
|
+
|
219
|
+
describe "It should be possible to use aliased associations" do
|
220
|
+
it { AliasedTask.create(:name => 'foo', :project_alias => @project2).valid?.should == true }
|
221
|
+
end
|
222
|
+
|
223
|
+
# Additional default_scopes
|
147
224
|
describe 'When dealing with a user defined default_scope' do
|
148
225
|
before do
|
149
226
|
@account = Account.create!(:name => 'foo')
|
@@ -166,47 +243,16 @@ describe ActsAsTenant do
|
|
166
243
|
end
|
167
244
|
end
|
168
245
|
|
169
|
-
|
170
|
-
before do
|
171
|
-
@account = Account.create!(:name => 'foo')
|
172
|
-
@project = @account.projects.create!(:name => 'bar')
|
173
|
-
end
|
174
|
-
|
175
|
-
it { lambda {@project.account_id = @account.id + 1}.should raise_error }
|
176
|
-
end
|
177
|
-
|
178
|
-
describe 'tenant_id should be mutable, if not already set' do
|
179
|
-
before do
|
180
|
-
@account = Account.create!(:name => 'foo')
|
181
|
-
@project = Project.create!(:name => 'bar')
|
182
|
-
end
|
183
|
-
|
184
|
-
it { @project.account_id.should be_nil }
|
185
|
-
it { lambda { @project.account = @account }.should_not raise_error }
|
186
|
-
end
|
187
|
-
|
188
|
-
describe 'Associations can only be made with in-scope objects' do
|
189
|
-
before do
|
190
|
-
@account = Account.create!(:name => 'foo')
|
191
|
-
@project1 = Project.create!(:name => 'inaccessible_project', :account_id => @account.id + 1)
|
192
|
-
|
193
|
-
ActsAsTenant.current_tenant = @account
|
194
|
-
@project2 = Project.create!(:name => 'accessible_project')
|
195
|
-
@task = @project2.tasks.create!(:name => 'bar')
|
196
|
-
end
|
197
|
-
|
198
|
-
it { @task.update_attributes(:project_id => @project1.id).should == false }
|
199
|
-
end
|
200
|
-
|
246
|
+
# Validates_uniqueness
|
201
247
|
describe 'When using validates_uniqueness_to_tenant in a aat model' do
|
202
248
|
before do
|
203
|
-
|
204
|
-
ActsAsTenant.current_tenant =
|
205
|
-
|
249
|
+
account = Account.create!(:name => 'foo')
|
250
|
+
ActsAsTenant.current_tenant = account
|
251
|
+
Project.create!(:name => 'existing_name')
|
206
252
|
end
|
207
253
|
|
208
254
|
it 'should not be possible to create a duplicate within the same tenant' do
|
209
|
-
Project.create(:name => '
|
255
|
+
Project.create(:name => 'existing_name').valid?.should == false
|
210
256
|
end
|
211
257
|
|
212
258
|
it 'should be possible to create a duplicate outside the tenant scope' do
|
@@ -214,33 +260,27 @@ describe ActsAsTenant do
|
|
214
260
|
ActsAsTenant.current_tenant = account
|
215
261
|
Project.create(:name => 'bar').valid?.should == true
|
216
262
|
end
|
263
|
+
end
|
217
264
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
SubTask.create(:name => 'foo', :attribute2 => 'unique_scope').should_not be_valid
|
265
|
+
describe 'Handles user defined scopes' do
|
266
|
+
before do
|
267
|
+
UniqueTask.create!(:name => 'foo', :user_defined_scope => 'unique_scope')
|
222
268
|
end
|
269
|
+
|
270
|
+
it { UniqueTask.create(:name => 'foo', :user_defined_scope => 'another_scope').should be_valid }
|
271
|
+
it { UniqueTask.create(:name => 'foo', :user_defined_scope => 'unique_scope').should_not be_valid }
|
223
272
|
end
|
224
273
|
|
225
274
|
describe 'When using validates_uniqueness_of in a NON-aat model' do
|
226
275
|
before do
|
227
|
-
|
276
|
+
UnscopedModel.create!(:name => 'foo')
|
228
277
|
end
|
229
278
|
it 'should not be possible to create duplicates' do
|
230
|
-
|
279
|
+
UnscopedModel.create(:name => 'foo').valid?.should == false
|
231
280
|
end
|
232
281
|
end
|
233
282
|
|
234
|
-
|
235
|
-
it { SubTask.create(:name => 'foo').valid?.should == true }
|
236
|
-
end
|
237
|
-
|
238
|
-
describe "It should be possible to create and save an AaT-enabled child without it having a parent" do
|
239
|
-
@account = Account.create!(:name => 'baz')
|
240
|
-
ActsAsTenant.current_tenant = @account
|
241
|
-
Task.create(:name => 'bar').valid?.should == true
|
242
|
-
end
|
243
|
-
|
283
|
+
# ::with_tenant
|
244
284
|
describe "::with_tenant" do
|
245
285
|
it "should set current_tenant to the specified tenant inside the block" do
|
246
286
|
@account = Account.create!(:name => 'baz')
|
@@ -279,6 +319,7 @@ describe ActsAsTenant do
|
|
279
319
|
end
|
280
320
|
end
|
281
321
|
|
322
|
+
# Tenant required
|
282
323
|
context "tenant required" do
|
283
324
|
describe "raises exception if no tenant specified" do
|
284
325
|
before do
|
@@ -15,7 +15,7 @@ class ApplicationController2 < ActionController::Base
|
|
15
15
|
current_account.name = 'account1'
|
16
16
|
set_current_tenant(current_account)
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
end
|
20
20
|
|
21
21
|
# Start testing
|
@@ -25,7 +25,7 @@ describe ApplicationController2, :type => :controller do
|
|
25
25
|
render :text => "custom called"
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
it 'Finds the correct tenant using the filter command' do
|
30
30
|
get :index
|
31
31
|
ActsAsTenant.current_tenant.name.should eq 'account1'
|
@@ -15,14 +15,14 @@ describe ApplicationController, :type => :controller do
|
|
15
15
|
render :text => "custom called"
|
16
16
|
end
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it 'Finds the correct tenant with a subdomain.example.com' do
|
20
20
|
@request.host = "account1.example.com"
|
21
21
|
Account.should_receive(:where).with({subdomain: 'account1'}) {['account1']}
|
22
22
|
get :index
|
23
23
|
ActsAsTenant.current_tenant.should eq 'account1'
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
it 'Finds the correct tenant with a www.subdomain.example.com' do
|
27
27
|
@request.host = "www.account1.example.com"
|
28
28
|
Account.should_receive(:where).with({subdomain: 'account1'}) {['account1']}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_tenant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Erwin Matthijssen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: request_store
|