leases 0.0.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +15 -3
- data/Gemfile +13 -0
- data/README.md +28 -0
- data/leases.gemspec +3 -3
- data/lib/leases/controller.rb +9 -2
- data/lib/leases/model/base.rb +29 -7
- data/lib/leases/model/callbacks.rb +11 -6
- data/lib/leases/model.rb +19 -0
- data/lib/leases/version.rb +1 -1
- data/lib/leases.rb +43 -1
- data/spec/leases_spec.rb +11 -0
- data/spec/spec_helper.rb +1 -0
- metadata +14 -8
data/.travis.yml
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
- 1.9.3
|
4
|
+
- 2.0.0
|
5
|
+
- 2.1.1
|
6
|
+
- ruby-head
|
7
|
+
|
8
|
+
env:
|
9
|
+
- "RAILS_VERSION=3.1.0"
|
10
|
+
- "RAILS_VERSION=3.2.0"
|
11
|
+
- "RAILS_VERSION=4.0.0"
|
12
|
+
- "RAILS_VERSION=master"
|
13
|
+
|
14
|
+
matrix:
|
15
|
+
allow_failures:
|
16
|
+
- env: "RAILS_VERSION=master"
|
17
|
+
- rvm: ruby-head
|
data/Gemfile
CHANGED
@@ -2,3 +2,16 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in leases.gemspec
|
4
4
|
gemspec
|
5
|
+
|
6
|
+
rails_version = ENV["RAILS_VERSION"] || "default"
|
7
|
+
|
8
|
+
rails = case rails_version
|
9
|
+
when "master"
|
10
|
+
{github: "rails/rails"}
|
11
|
+
when "default"
|
12
|
+
">= 3.2.0"
|
13
|
+
else
|
14
|
+
"~> #{rails_version}"
|
15
|
+
end
|
16
|
+
|
17
|
+
gem "rails", rails
|
data/README.md
CHANGED
@@ -4,6 +4,18 @@
|
|
4
4
|
|
5
5
|
Database multi-tenancy for Rails.
|
6
6
|
|
7
|
+
## Supported Rails versions
|
8
|
+
|
9
|
+
- Rails 3.1.x
|
10
|
+
- Rails 3.2.x
|
11
|
+
- Rails 4.0.x
|
12
|
+
|
13
|
+
## Supported Ruby versions
|
14
|
+
|
15
|
+
- Ruby 1.9.3
|
16
|
+
- Ruby 2.0.0
|
17
|
+
- Ruby 2.1.1
|
18
|
+
|
7
19
|
## Installation
|
8
20
|
|
9
21
|
Add this line to your Gemfile and run `bundle`.
|
@@ -81,6 +93,22 @@ end
|
|
81
93
|
|
82
94
|
We're using `apartment` for managing and switching databases. This is a fantastic gem that you should check out: https://github.com/influitive/apartment. Apartment supports MySQL and PostgreSQL.
|
83
95
|
|
96
|
+
## Background processing
|
97
|
+
|
98
|
+
We recommend using `apartment-sidekiq` to process background jobs (https://github.com/influitive/apartment-sidekiq). This is a zero-configuration gem that enables background processing in a tenant context.
|
99
|
+
|
100
|
+
Doing it yourself is also possible, here is a simple example:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
class SomeWorker
|
104
|
+
def some_process(account_id)
|
105
|
+
Account.find(account_id).visit do
|
106
|
+
# Your processing here
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
84
112
|
## Migrating
|
85
113
|
|
86
114
|
```
|
data/leases.gemspec
CHANGED
@@ -17,12 +17,12 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ['lib']
|
19
19
|
|
20
|
-
gem.add_development_dependency 'bundler',
|
20
|
+
gem.add_development_dependency 'bundler', '>= 1.3.0'
|
21
21
|
gem.add_development_dependency 'rake'
|
22
|
-
gem.add_development_dependency 'rspec',
|
22
|
+
gem.add_development_dependency 'rspec', '>= 2.11'
|
23
23
|
gem.add_development_dependency 'rspec-rails', '>= 2.11'
|
24
24
|
gem.add_development_dependency 'sqlite3'
|
25
25
|
gem.add_development_dependency 'with_model'
|
26
26
|
|
27
|
-
gem.add_dependency 'apartment', '
|
27
|
+
gem.add_dependency 'apartment', '>= 0.24.2'
|
28
28
|
end
|
data/lib/leases/controller.rb
CHANGED
@@ -11,9 +11,13 @@ module Leases
|
|
11
11
|
|
12
12
|
module ClassMethods
|
13
13
|
|
14
|
+
##
|
14
15
|
# Uses a leaser as the context in a controller.
|
15
16
|
#
|
16
|
-
#
|
17
|
+
# === Example
|
18
|
+
#
|
19
|
+
# visit_as :current_account
|
20
|
+
#
|
17
21
|
def visit_as(leaser)
|
18
22
|
around_filter do |c, block|
|
19
23
|
c.send(leaser).visit(&block)
|
@@ -22,8 +26,11 @@ module Leases
|
|
22
26
|
|
23
27
|
end
|
24
28
|
|
29
|
+
##
|
30
|
+
# Returns the current leaser. This is also a helper method.
|
31
|
+
#
|
25
32
|
def current_leaser
|
26
|
-
|
33
|
+
Leases.current
|
27
34
|
end
|
28
35
|
|
29
36
|
end
|
data/lib/leases/model/base.rb
CHANGED
@@ -11,8 +11,10 @@ module Leases
|
|
11
11
|
|
12
12
|
end
|
13
13
|
|
14
|
+
##
|
14
15
|
# Name of the leaser, used for naming the database.
|
15
16
|
# This can be set in the leaser_options. Must be unique.
|
17
|
+
#
|
16
18
|
def leaser_name
|
17
19
|
name = self.class.leases_options[:name]
|
18
20
|
|
@@ -25,26 +27,38 @@ module Leases
|
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
30
|
+
##
|
28
31
|
# Enter the leaser-context.
|
29
32
|
#
|
30
|
-
#
|
33
|
+
# === Example
|
34
|
+
#
|
35
|
+
# account.enter
|
36
|
+
#
|
31
37
|
def enter
|
32
38
|
Apartment::Database.switch(leaser_name)
|
33
|
-
|
39
|
+
Leases.current = self
|
34
40
|
end
|
35
41
|
|
42
|
+
##
|
36
43
|
# Leave the leaser-context.
|
37
44
|
#
|
38
|
-
#
|
45
|
+
# === Example
|
46
|
+
#
|
47
|
+
# account.leave
|
48
|
+
#
|
39
49
|
def leave
|
40
|
-
|
50
|
+
Leases.current = nil
|
41
51
|
Apartment::Database.reset
|
42
52
|
end
|
43
53
|
|
54
|
+
##
|
44
55
|
# Visit a leaser by entering and leaving.
|
45
56
|
# Very useful for executing code in a leaser-context
|
46
57
|
#
|
47
|
-
#
|
58
|
+
# === Example
|
59
|
+
#
|
60
|
+
# account.visit { User.find(1) }
|
61
|
+
#
|
48
62
|
def visit(&block)
|
49
63
|
enter
|
50
64
|
begin
|
@@ -54,18 +68,26 @@ module Leases
|
|
54
68
|
end
|
55
69
|
end
|
56
70
|
|
71
|
+
##
|
57
72
|
# Create a new lease.
|
58
73
|
# This is usually called when a model is created.
|
59
74
|
#
|
60
|
-
#
|
75
|
+
# === Example
|
76
|
+
#
|
77
|
+
# account.lease!
|
78
|
+
#
|
61
79
|
def lease!
|
62
80
|
Apartment::Database.create(leaser_name)
|
63
81
|
end
|
64
82
|
|
83
|
+
##
|
65
84
|
# Break a lease.
|
66
85
|
# This is usually called when a model is destroyed.
|
67
86
|
#
|
68
|
-
#
|
87
|
+
# === Example
|
88
|
+
#
|
89
|
+
# account.break!
|
90
|
+
#
|
69
91
|
def break!
|
70
92
|
Apartment::Database.drop(leaser_name)
|
71
93
|
end
|
@@ -4,6 +4,17 @@ module Leases
|
|
4
4
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
|
+
##
|
8
|
+
# Model callbacks
|
9
|
+
#
|
10
|
+
# === Examples
|
11
|
+
#
|
12
|
+
# on_enter :do_something
|
13
|
+
# on_leave :do_something
|
14
|
+
# on_lease :do_something
|
15
|
+
# on_break :do_something
|
16
|
+
#
|
17
|
+
|
7
18
|
included do
|
8
19
|
|
9
20
|
## Callbacks
|
@@ -15,12 +26,6 @@ module Leases
|
|
15
26
|
|
16
27
|
define_model_callbacks :enter, :leave, :lease, :break
|
17
28
|
|
18
|
-
# Define callback aliases
|
19
|
-
#
|
20
|
-
# => on_enter :method
|
21
|
-
# => on_leave :method
|
22
|
-
# => on_lease :method
|
23
|
-
# => on_break :method
|
24
29
|
class << self
|
25
30
|
alias :on_enter :after_enter
|
26
31
|
alias :on_leave :after_leave
|
data/lib/leases/model.rb
CHANGED
@@ -8,6 +8,15 @@ module Leases
|
|
8
8
|
|
9
9
|
module ClassMethods
|
10
10
|
|
11
|
+
##
|
12
|
+
# Marks model as a leaser.
|
13
|
+
#
|
14
|
+
# === Examples
|
15
|
+
#
|
16
|
+
# leases
|
17
|
+
# leases :name => :slug
|
18
|
+
# leases :name => Proc.new { |c| "acount_#{c.id}" }
|
19
|
+
#
|
11
20
|
def leases(options={})
|
12
21
|
include Base
|
13
22
|
include Callbacks
|
@@ -18,6 +27,16 @@ module Leases
|
|
18
27
|
self.leases_options = options
|
19
28
|
end
|
20
29
|
|
30
|
+
##
|
31
|
+
# Marks model as a shared model.
|
32
|
+
# This prevents the model being multi-tenant.
|
33
|
+
#
|
34
|
+
# === Example
|
35
|
+
#
|
36
|
+
# class User < ActiveRecord::Base
|
37
|
+
# shared_by_leasers
|
38
|
+
# end
|
39
|
+
#
|
21
40
|
def shared_by_leasers
|
22
41
|
Apartment.excluded_models ||= []
|
23
42
|
Apartment.excluded_models += [self.name]
|
data/lib/leases/version.rb
CHANGED
data/lib/leases.rb
CHANGED
@@ -10,9 +10,13 @@ module Leases
|
|
10
10
|
attr_accessor :leasers
|
11
11
|
self.leasers = []
|
12
12
|
|
13
|
+
##
|
13
14
|
# Add leaser to array of leasers.
|
14
15
|
#
|
15
|
-
#
|
16
|
+
# === Example
|
17
|
+
#
|
18
|
+
# leasing(Account)
|
19
|
+
#
|
16
20
|
def leasing(object)
|
17
21
|
self.leasers << object.name
|
18
22
|
self.leasers.uniq!
|
@@ -22,6 +26,17 @@ module Leases
|
|
22
26
|
object
|
23
27
|
end
|
24
28
|
|
29
|
+
##
|
30
|
+
# Leaser names currently used in the app
|
31
|
+
#
|
32
|
+
# === Example
|
33
|
+
#
|
34
|
+
# Leases.leaser_names
|
35
|
+
#
|
36
|
+
# === Returns
|
37
|
+
#
|
38
|
+
# [Array] List of leaser names
|
39
|
+
#
|
25
40
|
def leaser_names(preload=true)
|
26
41
|
Rails.application.eager_load! if preload
|
27
42
|
|
@@ -31,4 +46,31 @@ module Leases
|
|
31
46
|
end.flatten
|
32
47
|
end
|
33
48
|
|
49
|
+
##
|
50
|
+
# Returns the current leaser.
|
51
|
+
# This method uses Thread.current and is completely thread-safe.
|
52
|
+
#
|
53
|
+
# === Example
|
54
|
+
#
|
55
|
+
# Leases.current
|
56
|
+
#
|
57
|
+
# === Returns
|
58
|
+
#
|
59
|
+
# [Object] The current leaser
|
60
|
+
#
|
61
|
+
def current
|
62
|
+
Thread.current[:leaser]
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# Sets the current leaser.
|
67
|
+
#
|
68
|
+
# === Example
|
69
|
+
#
|
70
|
+
# Leases.current = account
|
71
|
+
#
|
72
|
+
def current=(leaser)
|
73
|
+
Thread.current[:leaser] = leaser
|
74
|
+
end
|
75
|
+
|
34
76
|
end
|
data/spec/leases_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: leases
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-02-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 1.
|
21
|
+
version: 1.3.0
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 1.
|
29
|
+
version: 1.3.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: rake
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,17 +112,17 @@ dependencies:
|
|
112
112
|
requirement: !ruby/object:Gem::Requirement
|
113
113
|
none: false
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ! '>='
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 0.
|
117
|
+
version: 0.24.2
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
none: false
|
122
122
|
requirements:
|
123
|
-
- -
|
123
|
+
- - ! '>='
|
124
124
|
- !ruby/object:Gem::Version
|
125
|
-
version: 0.
|
125
|
+
version: 0.24.2
|
126
126
|
description: Database multi-tenancy for Rails.
|
127
127
|
email:
|
128
128
|
- mail@arjen.me
|
@@ -162,12 +162,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
162
162
|
- - ! '>='
|
163
163
|
- !ruby/object:Gem::Version
|
164
164
|
version: '0'
|
165
|
+
segments:
|
166
|
+
- 0
|
167
|
+
hash: -4143158918345724043
|
165
168
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
166
169
|
none: false
|
167
170
|
requirements:
|
168
171
|
- - ! '>='
|
169
172
|
- !ruby/object:Gem::Version
|
170
173
|
version: '0'
|
174
|
+
segments:
|
175
|
+
- 0
|
176
|
+
hash: -4143158918345724043
|
171
177
|
requirements: []
|
172
178
|
rubyforge_project:
|
173
179
|
rubygems_version: 1.8.24
|