acts_as_tenant 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZDM3YTQ2MDk4YjRjZGRkNDlkMjVlNjVhYmE4MDhlYTZlZDcxY2JlNQ==
4
+ MDI0NjdkNWMzYTNjMDk2OTI4YjIxMmM1YmNmOThmOGVkYmU5MGQ1Yg==
5
5
  data.tar.gz: !binary |-
6
- YjIxMTk0YzRmMDg1MmZhNTk2ZDRjMjZiODE4YTA5ZTA1MDgyMzc1OA==
6
+ MjIxYTJjNmU0MTI1ZGJiZjEyNDNiOTcyMjhjNDk5Yjg5ZjExZDA3ZA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZjI5MTQzMDEzZTJhYjBiYWI1NjQyOTdhNjhkZTViZGRhZGVkYTVlMWE2MjFk
10
- NzE2YzMzMmY1YTJhZGUwN2E3MzgzOWQ1M2EwZjFlZWZjMzQ4MTAwMjFmMWUx
11
- NGIzYmVhYTAwNGRhZDUzZWQyMzkzMDIyOTJlM2YxZWY5OTM0OTg=
9
+ MzUxZmM0MzIyMjM1NWMxMThmNjk5NDE0NmUyYzNjMDk3NWNlODI0NWM3YWIw
10
+ NjVjMmMxOGZhODRjZDJiOTRmYjJkZjQ3YmJjZDc0YzgwZTBiNDRmY2ZkMjdk
11
+ MzU2MTBlYTZjM2EzODM1NTY4OGVkMGU3YzU5ZTA3MzdjMzA1ODc=
12
12
  data.tar.gz: !binary |-
13
- NzY1MDRhMzUxYzgxNzRhYzAxZGYzOTk5OTJiMGUzMzU2ODUwMGMwNTM0MmJh
14
- M2FhOWQxMmExNzYyMjM0NThiZDY4MDM0ZDVjOWIwMDI2NzFhMDQ4YzdhNmU1
15
- ZjhiMzY1MGZkODJmY2E2MjlmNjAwNzkxMTdmNzlkMTljM2IxM2Y=
13
+ YjY1ZjM4Yzc5ZTJkZTU3Y2YyNDU1MjMxNjI0OGVlYzQ1NDA2ODA3NTgzY2Ex
14
+ Zjg1MGM5YTdiMDNkNWQwZTUxZGZlZDljNmEzYjYxZDEzYmM3NTJmYjQxZDVi
15
+ NGEyMGY2MGE4MzRmMzFjMzU3OWZjZWE0NDg0ZTQ1NGMxZmYwOWY=
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ 0.3.4
2
+ -----
3
+ * Fix to a bug introduced in 0.3.2
4
+
1
5
  0.3.3
2
6
  -----
3
7
  * Support user defined foreign keys on scoped models
@@ -6,7 +10,6 @@
6
10
  -----
7
11
  * correctly support nested models with has_many :through (thx dexion)
8
12
  * Support 'www.subdomain.example.com' (thx wtfiwtz)
9
- * Support user defined foreign keys on scoped models
10
13
  * Support setting `tenant_id` on scoped models if the `tenant_id` is nil (thx Matt Wilson)
11
14
 
12
15
  0.3.1
data/README.md CHANGED
@@ -136,6 +136,16 @@ end
136
136
 
137
137
  * `config.require_tenant` when set to true will raise an ActsAsTenant::NoTenant error whenever a query is made without a tenant set.
138
138
 
139
+ Sidekiq support
140
+ ---------------
141
+
142
+ ActsAsTenant supports [Sidekiq](http://sidekiq.org/). A background processing library.
143
+ Add the following code to your `config/initializer/acts_as_tenant.rb`:
144
+
145
+ ```ruby
146
+ require 'acts_as_tenant/sidekiq'
147
+ ```
148
+
139
149
  Note on testing
140
150
  ---------------
141
151
  Whenever you set the `current_tenant` in your tests, either through integration tests or directly by calling `ActsAsTenant.current_tenant = some_tenant`, make sure to clean up the tenant after each test by calling `ActsAsTenant.current_tenant = nil`.
@@ -28,4 +28,6 @@ Gem::Specification.new do |s|
28
28
  s.add_development_dependency('database_cleaner')
29
29
  s.add_development_dependency('sqlite3')
30
30
  s.add_development_dependency('debugger')
31
+
32
+ s.add_development_dependency('sidekiq')
31
33
  end
@@ -42,16 +42,12 @@ module ActsAsTenant
42
42
 
43
43
  module ClassMethods
44
44
  def acts_as_tenant(tenant = :account, options = {})
45
-
46
45
  ActsAsTenant.set_tenant_klass(tenant)
47
46
 
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
47
+ # Create the association
48
+ valid_options = options.slice(:foreign_key, :class_name)
49
+ fkey = valid_options[:foreign_key] || ActsAsTenant.fkey
50
+ belongs_to tenant, valid_options
55
51
 
56
52
  default_scope lambda {
57
53
  if ActsAsTenant.configuration.require_tenant && ActsAsTenant.current_tenant.nil?
@@ -95,12 +91,17 @@ module ActsAsTenant
95
91
  end
96
92
 
97
93
  define_method "#{ActsAsTenant.tenant_klass.to_s}" do
98
- return ActsAsTenant.current_tenant if send(fkey) == ActsAsTenant.current_tenant.id
99
- super()
94
+ if !ActsAsTenant.current_tenant.nil? && send(fkey) == ActsAsTenant.current_tenant.id
95
+ return ActsAsTenant.current_tenant
96
+ else
97
+ super()
98
+ end
100
99
  end
101
100
 
102
- def scoped_by_tenant?
103
- true
101
+ class << self
102
+ def scoped_by_tenant?
103
+ true
104
+ end
104
105
  end
105
106
  end
106
107
 
@@ -0,0 +1,43 @@
1
+ module ActsAsTenant::Sidekiq
2
+ # Get the current tenant and store in the message to be sent to Sidekiq.
3
+ class Client
4
+ def call(worker_class, msg, queue)
5
+ msg['acts_as_tenant'] ||=
6
+ {
7
+ 'class' => ActsAsTenant.current_tenant.class.name,
8
+ 'id' => ActsAsTenant.current_tenant.id
9
+ } if ActsAsTenant.current_tenant.present?
10
+
11
+ yield
12
+ end
13
+ end
14
+
15
+ # Pull the tenant out and run the current thread with it.
16
+ class Server
17
+ def call(worker_class, msg, queue)
18
+ if msg.has_key?('acts_as_tenant')
19
+ account = msg['acts_as_tenant']['class'].constantize.find msg['acts_as_tenant']['id']
20
+ ActsAsTenant.with_tenant account do
21
+ yield
22
+ end
23
+ else
24
+ yield
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ Sidekiq.configure_client do |config|
31
+ config.client_middleware do |chain|
32
+ chain.add ActsAsTenant::Sidekiq::Client
33
+ end
34
+ end
35
+
36
+ Sidekiq.configure_server do |config|
37
+ config.client_middleware do |chain|
38
+ chain.add ActsAsTenant::Sidekiq::Client
39
+ end
40
+ config.server_middleware do |chain|
41
+ chain.add ActsAsTenant::Sidekiq::Server
42
+ end
43
+ end
@@ -1,3 +1,3 @@
1
1
  module ActsAsTenant
2
- VERSION = "0.3.3"
2
+ VERSION = "0.3.4"
3
3
  end
@@ -109,10 +109,14 @@ describe ActsAsTenant do
109
109
  it { ActsAsTenant.current_tenant == :foo }
110
110
  end
111
111
 
112
- describe 'is_scoped_as_tenant should return the correct value' do
112
+ describe 'is_scoped_as_tenant should return the correct value when true' do
113
113
  it {Project.respond_to?(:scoped_by_tenant?).should == true}
114
114
  end
115
115
 
116
+ describe 'is_scoped_as_tenant should return the correct value when false' do
117
+ it {UnscopedModel.respond_to?(:scoped_by_tenant?).should == false}
118
+ end
119
+
116
120
  describe 'tenant_id should be immutable, if already set' do
117
121
  before do
118
122
  @account = Account.create!(:name => 'foo')
@@ -174,6 +178,24 @@ describe ActsAsTenant do
174
178
  it { @projects.count.should == 2 }
175
179
  end
176
180
 
181
+ describe 'Querying the tenant from a scoped model without a tenant set' do
182
+ before do
183
+ @project = Project.create!(:name => 'bar')
184
+ end
185
+
186
+ it { @project.account }
187
+ end
188
+
189
+ describe 'Querying the tenant from a scoped model with a tenant set' do
190
+ before do
191
+ @account = Account.create!(:name => 'foo')
192
+ @project = @account.projects.create!(:name => 'foobar')
193
+ ActsAsTenant.current_tenant= @account1
194
+ end
195
+
196
+ it { @project.account }
197
+ end
198
+
177
199
  # Associations
178
200
  describe 'Associations should be correctly scoped by current tenant' do
179
201
  before do
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+ require 'sidekiq'
3
+ require 'acts_as_tenant/sidekiq'
4
+
5
+ describe ActsAsTenant::Sidekiq do
6
+ after { ActsAsTenant.current_tenant = nil }
7
+ let(:account) { Account.new(id: 1234) }
8
+ let(:message) { { 'acts_as_tenant' => { 'class' => 'Account', 'id' => 1234 } } }
9
+
10
+ describe ActsAsTenant::Sidekiq::Client do
11
+ subject { ActsAsTenant::Sidekiq::Client.new }
12
+
13
+ it 'saves tenant if present' do
14
+ ActsAsTenant.current_tenant = account
15
+
16
+ msg = {}
17
+ subject.call(nil, msg, nil) { }
18
+ expect(msg).to eq message
19
+ end
20
+
21
+ it 'does not set tenant if not present' do
22
+ expect(ActsAsTenant.current_tenant).to be_nil
23
+
24
+ msg = {}
25
+ subject.call(nil, msg, nil) { }
26
+ expect(msg).not_to eq message
27
+ end
28
+ end
29
+
30
+ describe ActsAsTenant::Sidekiq::Server do
31
+ subject { ActsAsTenant::Sidekiq::Server.new }
32
+
33
+ it 'restores tenant if tenant saved' do
34
+ expect(Account).to receive(:find).with(1234).once { account }
35
+
36
+ msg = message
37
+ subject.call(nil, msg, nil) do
38
+ expect(ActsAsTenant.current_tenant).to be_a_kind_of Account
39
+ end
40
+ expect(ActsAsTenant.current_tenant).to be_nil
41
+ end
42
+
43
+ it 'runs without tenant if no tenant saved' do
44
+ expect(Account).not_to receive(:find)
45
+
46
+ msg = {}
47
+ subject.call(nil, msg, nil) do
48
+ expect(ActsAsTenant.current_tenant).to be_nil
49
+ end
50
+ expect(ActsAsTenant.current_tenant).to be_nil
51
+ end
52
+ end
53
+
54
+ describe 'Sidekiq configuration' do
55
+ describe 'client configuration' do
56
+ it 'includes ActsAsTenant client' do
57
+ expect(Sidekiq.client_middleware.exists?(ActsAsTenant::Sidekiq::Client)).to be_true
58
+ end
59
+ end
60
+
61
+ # unable to test server configuration
62
+ end
63
+ end
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.3
4
+ version: 0.3.4
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-05 00:00:00.000000000 Z
11
+ date: 2014-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: request_store
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ! '>='
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: sidekiq
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description: Integrates multi-tenancy into a Rails application in a convenient and
112
126
  out-of-your way manner
113
127
  email:
@@ -128,10 +142,12 @@ files:
128
142
  - lib/acts_as_tenant/controller_extensions.rb
129
143
  - lib/acts_as_tenant/errors.rb
130
144
  - lib/acts_as_tenant/model_extensions.rb
145
+ - lib/acts_as_tenant/sidekiq.rb
131
146
  - lib/acts_as_tenant/version.rb
132
147
  - rails/init.rb
133
148
  - spec/acts_as_tenant/configuration_spec.rb
134
149
  - spec/acts_as_tenant/model_extensions_spec.rb
150
+ - spec/acts_as_tenant/sidekiq_spec.rb
135
151
  - spec/acts_as_tenant/tenant_by_filter_spec.rb
136
152
  - spec/acts_as_tenant/tenant_by_subdomain_spec.rb
137
153
  - spec/database.yml
@@ -162,6 +178,7 @@ summary: Add multi-tenancy to Rails applications using a shared db strategy
162
178
  test_files:
163
179
  - spec/acts_as_tenant/configuration_spec.rb
164
180
  - spec/acts_as_tenant/model_extensions_spec.rb
181
+ - spec/acts_as_tenant/sidekiq_spec.rb
165
182
  - spec/acts_as_tenant/tenant_by_filter_spec.rb
166
183
  - spec/acts_as_tenant/tenant_by_subdomain_spec.rb
167
184
  - spec/database.yml