acts_as_tenant 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 CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ae0af3ec60e0f5aec616181f0cb84dbf819838d5
4
- data.tar.gz: 24f836a129e42dbe7bf60aff0eb5cf3942eabc4d
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTdlZmJkZjFiNWQ5YzUxNDM0OWJiOWEzYWMzZTIzZWM3ZmMzN2RmOA==
5
+ data.tar.gz: !binary |-
6
+ NTViNTg4MDVkYjIwYmY4Y2VlZWY0NGVkNmE2MzEzNjk2ODE5YjEwOA==
5
7
  SHA512:
6
- metadata.gz: d5946028e86ba16bde4ed1ad232b2f89d75302111e44bcb765e144688e16f21c697d1951fae80160e5263c96c43871380e007a2ef813631278c932b2896f7e2c
7
- data.tar.gz: 2a2f574538b2507d3837b1d6d3919acf409df8599afded9127c7d991baac5ba40f85e77f135ae1655bacce560ffe14672b462a43b909958c059ede1e17f4ca0a
8
+ metadata.gz: !binary |-
9
+ MzZlMWJmNzAyZGQ2NDUwYWFmYjIzN2Q3YjliZDhlMjA4NGVjNzcwMGE4Yzc1
10
+ MzRmOGZmNTE0Yzk3NTY3YTI5ZTU2ZTBhNDczYTlmZjU0Y2JjYWY1MDM5ODE5
11
+ NTNhODA2ZjczYzk4Y2VkZjg4MDhmYTNlMDc5Y2UzZjgyNzBmZDA=
12
+ data.tar.gz: !binary |-
13
+ MjM2NzliNjViYjlkNjQyNjdmODNiMWY2MGFkODQ1ZjJiODQ1YjRjMzJkOWM2
14
+ MGFjNjJkNWVhNDkxMTE1NGZmZGIwZDM2ODA0ZWE3MmM0ZDQxMGNmYTcwMTVh
15
+ YzM3OWU5ZjUyYTJmZmExYTEyMDFiY2YyZmIzZThhYzhlMGYxNzI=
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ 0.3.2
2
+ -----
3
+ * correctly support nested models with has_many :through (thx dexion)
4
+ * Support 'www.subdomain.example.com' (thx wtfiwtz)
5
+ * Support setting `tenant_id` on scoped models if the `tenant_id` is nil (thx Matt Wilson)
6
+
1
7
  0.3.1
2
8
  -----
3
9
  * Added support for Rails 4
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  Acts As Tenant
2
2
  ==============
3
3
 
4
+ [![Build Status](https://travis-ci.org/ErwinM/acts_as_tenant.png)](https://travis-ci.org/ErwinM/acts_as_tenant)
5
+
4
6
  **Note**: acts_as_tenant was introduced in this [blog post](http://www.rollcallapp.com/blog/2011/10/03/adding-multi-tenancy-to-your-rails-app-acts-as-tenant).
5
7
 
6
8
  This gem was born out of our own need for a fail-safe and out-of-the-way manner to add multi-tenancy to our Rails app through a shared database strategy, that integrates (near) seamless with Rails.
data/Rakefile CHANGED
@@ -1 +1,5 @@
1
1
  require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task :default => :spec
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  #s.add_dependency('request_store', '>= 1.0.5')
25
25
 
26
26
  s.add_development_dependency('rspec')
27
+ s.add_development_dependency('rspec-rails')
27
28
  s.add_development_dependency('database_cleaner')
28
29
  s.add_development_dependency('sqlite3')
29
30
  s.add_development_dependency('debugger')
@@ -18,7 +18,7 @@ module ActsAsTenant
18
18
 
19
19
  private
20
20
  def find_tenant_by_subdomain
21
- ActsAsTenant.current_tenant = tenant_class.where(tenant_column => request.subdomains.first).first
21
+ ActsAsTenant.current_tenant = tenant_class.where(tenant_column => request.subdomains.last).first
22
22
  end
23
23
 
24
24
  def current_tenant
@@ -29,8 +29,10 @@ module ActsAsTenant
29
29
  old_tenant = self.current_tenant
30
30
  self.current_tenant = tenant
31
31
  value = block.call
32
- self.current_tenant = old_tenant
33
32
  return value
33
+
34
+ ensure
35
+ self.current_tenant = old_tenant
34
36
  end
35
37
 
36
38
  module ModelExtensions
@@ -47,7 +49,7 @@ module ActsAsTenant
47
49
  if ActsAsTenant.configuration.require_tenant && ActsAsTenant.current_tenant.nil?
48
50
  raise ActsAsTenant::Errors::NoTenantSet
49
51
  end
50
- where({ActsAsTenant.fkey => ActsAsTenant.current_tenant.id}) if ActsAsTenant.current_tenant
52
+ where("#{self.table_name}.#{ActsAsTenant.fkey} = ?", ActsAsTenant.current_tenant.id) if ActsAsTenant.current_tenant
51
53
  }
52
54
 
53
55
  # Add the following validations to the receiving model:
@@ -74,13 +76,13 @@ module ActsAsTenant
74
76
  # - Add a helper method to verify if a model has been scoped by AaT
75
77
  #
76
78
  define_method "#{ActsAsTenant.fkey}=" do |integer|
77
- raise ActsAsTenant::Errors::TenantIsImmutable unless new_record?
78
- write_attribute("#{ActsAsTenant.fkey}", integer)
79
+ raise ActsAsTenant::Errors::TenantIsImmutable unless new_record? || send(ActsAsTenant.fkey).nil?
80
+ write_attribute("#{ActsAsTenant.fkey}", integer)
79
81
  end
80
82
 
81
- define_method "#{ActsAsTenant.tenant_klass.to_s}=" do |model|
82
- raise ActsAsTenant::Errors::TenantIsImmutable unless new_record?
83
- super(model)
83
+ define_method "#{ActsAsTenant.tenant_klass.to_s}=" do |model|
84
+ raise ActsAsTenant::Errors::TenantIsImmutable unless new_record? || send(ActsAsTenant.fkey).nil?
85
+ super(model)
84
86
  end
85
87
 
86
88
  def scoped_by_tenant?
@@ -1,3 +1,3 @@
1
1
  module ActsAsTenant
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -4,6 +4,7 @@ require 'spec_helper'
4
4
  ActiveRecord::Schema.define(:version => 1) do
5
5
  create_table :accounts, :force => true do |t|
6
6
  t.column :name, :string
7
+ t.column :subdomain, :string
7
8
  end
8
9
 
9
10
  create_table :projects, :force => true do |t|
@@ -165,7 +166,7 @@ describe ActsAsTenant do
165
166
  end
166
167
  end
167
168
 
168
- describe 'tenant_id should be immutable' do
169
+ describe 'tenant_id should be immutable, if already set' do
169
170
  before do
170
171
  @account = Account.create!(:name => 'foo')
171
172
  @project = @account.projects.create!(:name => 'bar')
@@ -174,6 +175,16 @@ describe ActsAsTenant do
174
175
  it { lambda {@project.account_id = @account.id + 1}.should raise_error }
175
176
  end
176
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
+
177
188
  describe 'Associations can only be made with in-scope objects' do
178
189
  before do
179
190
  @account = Account.create!(:name => 'foo')
@@ -275,7 +286,7 @@ describe ActsAsTenant do
275
286
  @project1 = @account1.projects.create!(:name => 'foobar')
276
287
  ActsAsTenant.configuration.stub(require_tenant: true)
277
288
  end
278
-
289
+
279
290
  it "should raise an error when no tenant is provided" do
280
291
  expect { Project.all.load }.to raise_error(ActsAsTenant::Errors::NoTenantSet)
281
292
  end
@@ -0,0 +1,33 @@
1
+ require "spec_helper"
2
+
3
+ #Setup test specific ApplicationController
4
+ class Account
5
+ attr_accessor :name
6
+ end
7
+
8
+ class ApplicationController2 < ActionController::Base
9
+ include Rails.application.routes.url_helpers
10
+ set_current_tenant_through_filter
11
+ before_filter :your_method_that_finds_the_current_tenant
12
+
13
+ def your_method_that_finds_the_current_tenant
14
+ current_account = Account.new
15
+ current_account.name = 'account1'
16
+ set_current_tenant(current_account)
17
+ end
18
+
19
+ end
20
+
21
+ # Start testing
22
+ describe ApplicationController2, :type => :controller do
23
+ controller do
24
+ def index
25
+ render :text => "custom called"
26
+ end
27
+ end
28
+
29
+ it 'Finds the correct tenant using the filter command' do
30
+ get :index
31
+ ActsAsTenant.current_tenant.name.should eq 'account1'
32
+ end
33
+ end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ #Setup test specific ApplicationController
4
+ class Account; end # this is so the spec will work in isolation
5
+
6
+ class ApplicationController < ActionController::Base
7
+ include Rails.application.routes.url_helpers
8
+ set_current_tenant_by_subdomain
9
+ end
10
+
11
+ # Start testing
12
+ describe ApplicationController, :type => :controller do
13
+ controller do
14
+ def index
15
+ render :text => "custom called"
16
+ end
17
+ end
18
+
19
+ it 'Finds the correct tenant with a subdomain.example.com' do
20
+ @request.host = "account1.example.com"
21
+ Account.should_receive(:where).with({subdomain: 'account1'}) {['account1']}
22
+ get :index
23
+ ActsAsTenant.current_tenant.should eq 'account1'
24
+ end
25
+
26
+ it 'Finds the correct tenant with a www.subdomain.example.com' do
27
+ @request.host = "www.account1.example.com"
28
+ Account.should_receive(:where).with({subdomain: 'account1'}) {['account1']}
29
+ get :index
30
+ ActsAsTenant.current_tenant.should eq 'account1'
31
+ end
32
+ end
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,8 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
3
 
4
4
  require 'database_cleaner'
5
5
  require 'acts_as_tenant'
6
+ require 'rspec/rails'
7
+ require 'rails'
6
8
 
7
9
  config = YAML::load(IO.read(File.join(File.dirname(__FILE__), 'database.yml')))
8
10
  ActiveRecord::Base.logger = Logger.new(File.join(File.dirname(__FILE__), "debug.log"))
@@ -22,5 +24,14 @@ RSpec.configure do |config|
22
24
  DatabaseCleaner.clean
23
25
  ActsAsTenant.current_tenant = nil
24
26
  end
27
+
28
+ config.infer_base_class_for_anonymous_controllers = true
29
+ end
25
30
 
26
- end
31
+ # Setup a test app
32
+ module Rollcall
33
+ class Application < Rails::Application; end
34
+ end
35
+
36
+ Rollcall::Application.config.secret_token = '1234567890123456789012345678901234567890'
37
+ Rollcall::Application.config.secret_key_base = '1234567890123456789012345678901234567890'
metadata CHANGED
@@ -1,97 +1,111 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_tenant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erwin Matthijssen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-24 00:00:00.000000000 Z
11
+ date: 2014-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: request_store
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ! '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.0.5
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ! '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.0.5
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rails
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ! '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '3.1'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ! '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.1'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ! '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: database_cleaner
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - '>='
73
+ - - ! '>='
60
74
  - !ruby/object:Gem::Version
61
75
  version: '0'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - '>='
80
+ - - ! '>='
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: sqlite3
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - '>='
87
+ - - ! '>='
74
88
  - !ruby/object:Gem::Version
75
89
  version: '0'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - '>='
94
+ - - ! '>='
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: debugger
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - '>='
101
+ - - ! '>='
88
102
  - !ruby/object:Gem::Version
89
103
  version: '0'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - '>='
108
+ - - ! '>='
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
97
111
  description: Integrates multi-tenancy into a Rails application in a convenient and
@@ -118,6 +132,8 @@ files:
118
132
  - rails/init.rb
119
133
  - spec/acts_as_tenant/configuration_spec.rb
120
134
  - spec/acts_as_tenant/model_extensions_spec.rb
135
+ - spec/acts_as_tenant/tenant_by_filter_spec.rb
136
+ - spec/acts_as_tenant/tenant_by_subdomain_spec.rb
121
137
  - spec/database.yml
122
138
  - spec/spec_helper.rb
123
139
  homepage: http://www.rollcallapp.com/blog
@@ -129,22 +145,24 @@ require_paths:
129
145
  - lib
130
146
  required_ruby_version: !ruby/object:Gem::Requirement
131
147
  requirements:
132
- - - '>='
148
+ - - ! '>='
133
149
  - !ruby/object:Gem::Version
134
150
  version: '0'
135
151
  required_rubygems_version: !ruby/object:Gem::Requirement
136
152
  requirements:
137
- - - '>='
153
+ - - ! '>='
138
154
  - !ruby/object:Gem::Version
139
155
  version: '0'
140
156
  requirements: []
141
157
  rubyforge_project: acts_as_tenant
142
- rubygems_version: 2.0.3
158
+ rubygems_version: 2.2.0
143
159
  signing_key:
144
160
  specification_version: 4
145
161
  summary: Add multi-tenancy to Rails applications using a shared db strategy
146
162
  test_files:
147
163
  - spec/acts_as_tenant/configuration_spec.rb
148
164
  - spec/acts_as_tenant/model_extensions_spec.rb
165
+ - spec/acts_as_tenant/tenant_by_filter_spec.rb
166
+ - spec/acts_as_tenant/tenant_by_subdomain_spec.rb
149
167
  - spec/database.yml
150
168
  - spec/spec_helper.rb