acts_as_tenant 0.2.7 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ 0.2.8
2
+ -----
3
+ * Added dependencies to gemspec (thx aaronrenner)
4
+ * Added the `ActsAsTenant.with_tenant` block method (see readme) (thx aaronrenner)
5
+ * Acts_as_Tenant is now thread safe (thx davide)
6
+
1
7
  0.2.7
2
8
  -----
3
9
  * Changed the interface for passing in the current_tenant manually in the controller. `set_current_tenant_to` has been deprecated and replaced by `set_current_tenant_through_filter` declaration and the `set_current_tenant` method. See readme for details.
data/README.md CHANGED
@@ -31,7 +31,8 @@ There are two steps in adding multi-tenancy to your app with acts_as_tenant:
31
31
 
32
32
  Setting the current tenant
33
33
  --------------------------
34
- There are two ways to set the current tenant: (1) by using the subdomain to lookup the current tenant and (2) by passing in the current tenant yourself.
34
+ There are three ways to set the current tenant: (1) by using the subdomain to lookup the current tenant, (2) by setting the current tenant in the controller, and
35
+ (3) by setting the current tenant for a block.
35
36
 
36
37
  **Use the subdomain to lookup the current tenant**
37
38
 
@@ -40,7 +41,7 @@ There are two ways to set the current tenant: (1) by using the subdomain to look
40
41
  end
41
42
  This tells acts_as_tenant to use the current subdomain to identify the current tenant. In addition, it tells acts_as_tenant that tenants are represented by the Account model and this model has a column named 'subdomain' which can be used to lookup the Account using the actual subdomain. If ommitted, the parameters will default to the values used above.
42
43
 
43
- **OR Pass in the current tenant yourself**
44
+ **Setting the current tenant in a controller, manually**
44
45
 
45
46
  class ApplicationController < ActionController::Base
46
47
  set_current_tenant_through_filter
@@ -53,7 +54,17 @@ This tells acts_as_tenant to use the current subdomain to identify the current t
53
54
  end
54
55
  Setting the current_tenant yourself, requires you to declare `set_current_tenant_through_filter` at the top of your application_controller to tell acts_as_tenant that you are going to use a before_filter to setup the current tenant. Next you should actually setup that before_filter to fetch the current tenant and pass it to `acts_as_tenant` by using `set_current_tenant(current_tenant)` in the before_filter.
55
56
 
56
- **note:** If the current tenant is not set by either of these methods, Acts_as_tenant will be unable to apply the proper scope to your models. So make sure you use one of the two methods to tell acts_as_tenant about the current tenant.
57
+
58
+ **Setting the current tenant for a block**
59
+
60
+ ActsAsTenant.with_tenant(current_account) do
61
+ # Current tenant is set for all code in this block
62
+ end
63
+
64
+ This approach is useful when running background processes for a specified tenant. For example, by putting this in your worker's run method,
65
+ any code in this block will be scoped to the current tenant. All methods that set the current tenant are thread safe.
66
+
67
+ **note:** If the current tenant is not set by one of these methods, Acts_as_tenant will be unable to apply the proper scope to your models. So make sure you use one of the two methods to tell acts_as_tenant about the current tenant.
57
68
 
58
69
  Scoping your models
59
70
  -------------------
@@ -17,4 +17,10 @@ Gem::Specification.new do |s|
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
+
21
+ s.add_dependency('rails','>= 3.1')
22
+
23
+ s.add_development_dependency('rspec')
24
+ s.add_development_dependency('database_cleaner')
25
+ s.add_development_dependency('sqlite3')
20
26
  end
@@ -5,7 +5,30 @@ module ActsAsTenant
5
5
 
6
6
  class << self
7
7
  cattr_accessor :tenant_class
8
- attr_accessor :current_tenant
8
+
9
+ # This will also work whithin Fibers:
10
+ # http://devblog.avdi.org/2012/02/02/ruby-thread-locals-are-also-fiber-local/
11
+ def current_tenant=(tenant)
12
+ Thread.current[:current_tenant] = tenant
13
+ end
14
+
15
+ def current_tenant
16
+ Thread.current[:current_tenant]
17
+ end
18
+
19
+ # Sets the current_tenant within the given block
20
+ def with_tenant(tenant, &block)
21
+ if block.nil?
22
+ raise ArgumentError, "block required"
23
+ end
24
+
25
+ old_tenant = self.current_tenant
26
+ self.current_tenant = tenant
27
+
28
+ block.call
29
+
30
+ self.current_tenant= old_tenant
31
+ end
9
32
  end
10
33
 
11
34
  module ModelExtensions
@@ -1,3 +1,3 @@
1
1
  module ActsAsTenant
2
- VERSION = "0.2.7"
2
+ VERSION = "0.2.8"
3
3
  end
@@ -220,4 +220,31 @@ describe ActsAsTenant do
220
220
  ActsAsTenant.current_tenant = @account
221
221
  Task.create(:name => 'bar').valid?.should == true
222
222
  end
223
+
224
+ describe "::with_tenant" do
225
+ it "should set current_tenant to the specified tenant inside the block" do
226
+ @account = Account.create!(:name => 'baz')
227
+
228
+ ActsAsTenant.with_tenant(@account) do
229
+ ActsAsTenant.current_tenant.should eq(@account)
230
+ end
231
+ end
232
+
233
+
234
+ it "should return current_tenant to the previous tenant once exiting the block" do
235
+ @account1 = Account.create!(:name => 'foo')
236
+ @account2 = Account.create!(:name => 'bar')
237
+
238
+ ActsAsTenant.current_tenant = @account1
239
+ ActsAsTenant.with_tenant @account2 do
240
+
241
+ end
242
+
243
+ ActsAsTenant.current_tenant.should eq(@account1)
244
+ end
245
+
246
+ it "should raise an error when no block is provided" do
247
+ expect { ActsAsTenant.with_tenant(nil) }.to raise_error(ArgumentError, /block required/)
248
+ end
249
+ end
223
250
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_tenant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.2.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,52 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-24 00:00:00.000000000Z
13
- dependencies: []
12
+ date: 2012-11-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: &70247831625340 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '3.1'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70247831625340
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70247831624140 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70247831624140
36
+ - !ruby/object:Gem::Dependency
37
+ name: database_cleaner
38
+ requirement: &70247831623580 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70247831623580
47
+ - !ruby/object:Gem::Dependency
48
+ name: sqlite3
49
+ requirement: &70247831622820 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70247831622820
14
58
  description: Integrates multi-tenancy into a Rails application in a convenient and
15
59
  out-of-your way manner
16
60
  email: