leases 0.0.1

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.
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ /spec/leaser.sqlite3
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - ruby-head
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in leases.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Arjen Oosterkamp
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,100 @@
1
+ # Leases
2
+
3
+ Database multi-tenancy for Rails.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your Gemfile and run `bundle`.
8
+
9
+ ```
10
+ gem 'leases'
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ruby
16
+ # app/models/account.rb
17
+ class Account < ActiveRecord::Base
18
+ leases
19
+ end
20
+
21
+ # app/controllers/application_controller.rb
22
+ class ApplicationController < ActionController::Base
23
+ visit_as :current_account
24
+
25
+ protected
26
+
27
+ def current_account
28
+ @account
29
+ end
30
+ end
31
+ ```
32
+
33
+ That's it. Now you have a fully multi-tenant app.
34
+
35
+ ## More
36
+
37
+ ```ruby
38
+ # app/models/account.rb
39
+ class Account < ActiveRecord::Base
40
+
41
+ # Customize the leaser name (used for the database name)
42
+ leases :name => :slug
43
+ leases :name => Proc.new { |c| "acount_#{c.id}" }
44
+
45
+ # Callbacks
46
+ on_enter :set_something # => Called on :enter (part of visit)
47
+ on_leave :clear_something # => Called on :leave (part of visit)
48
+
49
+ on_lease :create_something # => Called on new lease
50
+ on_break :delete_something # => Called on break of lease
51
+
52
+ end
53
+
54
+ account = Account.create :name => 'John Doe' # => Calls account.lease! and sets up database 'account-1'
55
+
56
+ account.enter # => Switches to database 'account-1'
57
+ account.leave # => Switches back to regular database
58
+
59
+ account.visit do
60
+ # You are now in account database context
61
+ # Context is automatically cleared after visit
62
+ end
63
+
64
+ account.destroy # => Calls account.break! and deletes leaser database
65
+ ```
66
+
67
+ ## Shared models
68
+
69
+ By default only the leaser model is a shared model. The rest is stored in a separate database. There may be situations in which you want to have more shared models, such as a `User` model. You can configure this as such:
70
+
71
+ ```ruby
72
+ # app/models/user.rb
73
+ class User < ActiveRecord::Base
74
+ shared_by_leasers
75
+ end
76
+ ```
77
+
78
+ ## Under the hood
79
+
80
+ 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.
81
+
82
+ ## Migrating
83
+
84
+ ```
85
+ rake apartment:migrate
86
+ ```
87
+
88
+ This will migrate all leaser databases.
89
+
90
+ ## Other solutions
91
+
92
+ If you're looking for multi-tenancy without having multiple databases then you should check out acts_as_tenant: https://github.com/ErwinM/acts_as_tenant.
93
+
94
+ ## Contributing
95
+
96
+ 1. Fork it
97
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
98
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
99
+ 4. Push to the branch (`git push origin my-new-feature`)
100
+ 5. Create new Pull Request
@@ -0,0 +1,5 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task :default => :spec
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'leases/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'leases'
8
+ gem.version = Leases::VERSION
9
+ gem.authors = ['Arjen Oosterkamp']
10
+ gem.email = ['mail@arjen.me']
11
+ gem.description = %q{Database multi-tenancy for Rails.}
12
+ gem.summary = %q{Database multi-tenancy for Rails.}
13
+ gem.homepage = 'https://github.com/Arjeno/leases'
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_development_dependency 'bundler', '>= 1.0.0'
21
+ gem.add_development_dependency 'rake'
22
+ gem.add_development_dependency 'rspec', '>= 2.3'
23
+ gem.add_development_dependency 'rspec-rails', '~> 2.0'
24
+ gem.add_development_dependency 'sqlite3'
25
+ gem.add_development_dependency 'with_model'
26
+
27
+ gem.add_dependency 'rails', '>= 3.0'
28
+ gem.add_dependency 'apartment', '>= 0.20'
29
+ end
@@ -0,0 +1,34 @@
1
+ require 'leases/railtie'
2
+ require 'leases/version'
3
+ require 'leases/model'
4
+ require 'leases/controller'
5
+
6
+ module Leases
7
+
8
+ extend self
9
+
10
+ attr_accessor :leasers
11
+ self.leasers = []
12
+
13
+ # Add leaser to array of leasers.
14
+ #
15
+ # => leasing(Account)
16
+ def leasing(object)
17
+ self.leasers << object.name
18
+ self.leasers.uniq!
19
+
20
+ Apartment.database_names = Proc.new { Leases.leaser_names }
21
+
22
+ object
23
+ end
24
+
25
+ def leaser_names(preload=true)
26
+ Rails.application.eager_load! if preload
27
+
28
+ leasers.map do |l|
29
+ model = l.constantize
30
+ model.all.collect(&:leaser_name)
31
+ end.flatten
32
+ end
33
+
34
+ end
@@ -0,0 +1,32 @@
1
+ module Leases
2
+ module Controller
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+
8
+ helper_method :current_leaser
9
+
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ # Uses a leaser as the context in a controller.
15
+ #
16
+ # => visit_as :current_account
17
+ def visit_as(leaser)
18
+ around_filter do |c, block|
19
+ c.send(leaser).visit(&block)
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ def current_leaser
26
+ Thread.current[:leaser]
27
+ end
28
+
29
+ end
30
+ end
31
+
32
+ ActionController::Base.send(:include, Leases::Controller)
@@ -0,0 +1,32 @@
1
+ require 'leases/model/base'
2
+ require 'leases/model/callbacks'
3
+
4
+ module Leases
5
+ module Model
6
+
7
+ extend ActiveSupport::Concern
8
+
9
+ module ClassMethods
10
+
11
+ def leases(options={})
12
+ include Base
13
+ include Callbacks
14
+
15
+ shared_by_leasers
16
+
17
+ Leases.leasing(self)
18
+ self.leases_options = options
19
+ end
20
+
21
+ def shared_by_leasers
22
+ Apartment.excluded_models ||= []
23
+ Apartment.excluded_models += [self.name]
24
+ Apartment.excluded_models.uniq!
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+ end
31
+
32
+ ActiveRecord::Base.send(:include, Leases::Model)
@@ -0,0 +1,75 @@
1
+ module Leases
2
+ module Model
3
+ module Base
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+
9
+ cattr_accessor :leases_options
10
+ self.leases_options = {}
11
+
12
+ end
13
+
14
+ # Name of the leaser, used for naming the database.
15
+ # This can be set in the leaser_options. Must be unique.
16
+ def leaser_name
17
+ name = self.class.leases_options[:name]
18
+
19
+ if name.nil?
20
+ [self.class.name.parameterize, id].join('-')
21
+ elsif name.is_a?(Symbol)
22
+ send(name)
23
+ elsif name.is_a?(Proc)
24
+ name.call(self)
25
+ end
26
+ end
27
+
28
+ # Enter the leaser-context.
29
+ #
30
+ # => account.enter
31
+ def enter
32
+ Apartment::Database.switch(leaser_name)
33
+ Thread.current[:leaser] = self
34
+ end
35
+
36
+ # Leave the leaser-context.
37
+ #
38
+ # => account.leave
39
+ def leave
40
+ Thread.current[:leaser] = nil
41
+ Apartment::Database.reset
42
+ end
43
+
44
+ # Visit a leaser by entering and leaving.
45
+ # Very useful for executing code in a leaser-context
46
+ #
47
+ # => account.visit { User.find(1) }
48
+ def visit(&block)
49
+ enter
50
+ begin
51
+ yield
52
+ ensure
53
+ leave
54
+ end
55
+ end
56
+
57
+ # Create a new lease.
58
+ # This is usually called when a model is created.
59
+ #
60
+ # => account.lease!
61
+ def lease!
62
+ Apartment::Database.create(leaser_name)
63
+ end
64
+
65
+ # Break a lease.
66
+ # This is usually called when a model is destroyed.
67
+ #
68
+ # => account.break!
69
+ def break!
70
+ Apartment::Database.drop(leaser_name)
71
+ end
72
+
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,59 @@
1
+ module Leases
2
+ module Model
3
+ module Callbacks
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+
9
+ ## Callbacks
10
+
11
+ after_create :lease!
12
+ after_destroy :break!
13
+
14
+ ## Custom callbacks
15
+
16
+ define_model_callbacks :enter, :leave, :lease, :break
17
+
18
+ # Define callback aliases
19
+ #
20
+ # => on_enter :method
21
+ # => on_leave :method
22
+ # => on_lease :method
23
+ # => on_break :method
24
+ class << self
25
+ alias :on_enter :after_enter
26
+ alias :on_leave :after_leave
27
+ alias :on_lease :after_lease
28
+ alias :on_break :after_break
29
+ end
30
+
31
+ end
32
+
33
+ def enter
34
+ run_callbacks :enter do
35
+ super
36
+ end
37
+ end
38
+
39
+ def leave
40
+ run_callbacks :leave do
41
+ super
42
+ end
43
+ end
44
+
45
+ def lease!
46
+ run_callbacks :lease do
47
+ super
48
+ end
49
+ end
50
+
51
+ def break!
52
+ run_callbacks :break do
53
+ super
54
+ end
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,12 @@
1
+ require 'rails'
2
+ require 'apartment'
3
+
4
+ module Leases
5
+ class Railtie < Rails::Railtie
6
+
7
+ config.to_prepare do
8
+ Apartment.database_names = Proc.new { Leases.leaser_names }
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module Leases
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ class AnonymousController < ActionController::Base
4
+ include Rails.application.routes.url_helpers
5
+ def index
6
+ @account = Thread.current[:leaser]
7
+ @current_leaser = current_leaser
8
+ render :text => :none
9
+ end
10
+ end
11
+
12
+ describe Leases::Controller, :type => :controller do
13
+
14
+ with_model :Account do
15
+ table do |t|
16
+ t.string :name
17
+ t.timestamps
18
+ end
19
+ model do
20
+ leases
21
+ end
22
+ end
23
+
24
+ controller(AnonymousController) do
25
+ visit_as :current_account
26
+ end
27
+
28
+ let(:account) { Account.create(:name => 'John Doe') }
29
+
30
+ before(:each) do
31
+ controller.stub(:current_account).and_return(account)
32
+ get :index
33
+ end
34
+
35
+ it { assigns(:account).should == account }
36
+ it { assigns(:current_leaser).should == account }
37
+
38
+ end
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+
3
+ describe Leases::Model::Base do
4
+
5
+ with_model :Account do
6
+ table do |t|
7
+ t.string :name
8
+ t.string :slug
9
+ t.timestamps
10
+ end
11
+ end
12
+
13
+ before(:each) { Account.leases options }
14
+
15
+ let(:options) { {} }
16
+ let(:account) { Account.create(:name => 'John Doe', :slug => 'john-doe') }
17
+
18
+ subject { account }
19
+
20
+ describe :leaser_name do
21
+
22
+ context 'default' do
23
+
24
+ let(:options) { {} }
25
+
26
+ its(:leaser_name) { should == "account-#{account.id}" }
27
+
28
+ end
29
+
30
+ context 'with symbol' do
31
+
32
+ let(:options) { { :name => :slug } }
33
+
34
+ its(:leaser_name) { should == account.slug }
35
+
36
+ end
37
+
38
+ context 'with proc' do
39
+
40
+ let(:options) { { :name => Proc.new { |a| [a.id, a.name].join('-') } } }
41
+
42
+ its(:leaser_name) { should == "#{account.id}-#{account.name}" }
43
+
44
+ end
45
+
46
+ end
47
+
48
+ describe :enter do
49
+
50
+ after(:each) { account.enter }
51
+
52
+ it { Apartment::Database.should_receive(:switch).with(account.leaser_name) }
53
+ it { Thread.current[:leaser].id.should == account.id }
54
+
55
+ end
56
+
57
+ describe :leave do
58
+
59
+ after(:each) { account.leave }
60
+
61
+ it { Apartment::Database.should_receive(:reset) }
62
+ it { Thread.current[:leaser].should == nil }
63
+
64
+ end
65
+
66
+ describe :visit do
67
+
68
+ it 'should enter and leave' do
69
+ account.should_receive(:enter)
70
+ account.should_receive(:leave)
71
+
72
+ account.visit {}
73
+ end
74
+
75
+ end
76
+
77
+ describe :lease! do
78
+
79
+ after(:each) { account.lease! }
80
+
81
+ it { Apartment::Database.should_receive(:create).with(account.leaser_name) }
82
+
83
+ end
84
+
85
+ describe :break! do
86
+
87
+ after(:each) { account.break! }
88
+
89
+ it { Apartment::Database.should_receive(:drop).with(account.leaser_name) }
90
+
91
+ end
92
+
93
+ end
@@ -0,0 +1,169 @@
1
+ require 'spec_helper'
2
+
3
+ describe Leases::Model::Callbacks do
4
+
5
+ with_model :Account do
6
+ table do |t|
7
+ t.string :name
8
+ t.string :slug
9
+ t.timestamps
10
+ end
11
+ end
12
+
13
+ before(:each) { Account.leases }
14
+
15
+ let(:account) { Account.create }
16
+
17
+ subject { account }
18
+
19
+ describe :enter do
20
+
21
+ before(:each) do
22
+ account.stub(:_test_callback_before_enter)
23
+ account.stub(:_test_callback_after_enter)
24
+ Account.before_enter :_test_callback_before_enter
25
+ Account.after_enter :_test_callback_after_enter
26
+ end
27
+
28
+ after(:each) { account.enter }
29
+
30
+ it { account.should_receive(:_test_callback_before_enter) }
31
+ it { account.should_receive(:_test_callback_after_enter) }
32
+
33
+ describe :aliases do
34
+
35
+ describe :on_enter do
36
+
37
+ before(:each) do
38
+ account.stub(:_test_callback_on_enter)
39
+ Account.on_enter :_test_callback_on_enter
40
+ end
41
+
42
+ it { account.should_receive(:_test_callback_on_enter) }
43
+
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+
50
+ describe :leave do
51
+
52
+ before(:each) do
53
+ account.stub(:_test_callback_before_leave)
54
+ account.stub(:_test_callback_after_leave)
55
+ Account.before_leave :_test_callback_before_leave
56
+ Account.after_leave :_test_callback_after_leave
57
+ end
58
+
59
+ after(:each) { account.leave }
60
+
61
+ it { account.should_receive(:_test_callback_before_leave) }
62
+ it { account.should_receive(:_test_callback_after_leave) }
63
+
64
+ describe :aliases do
65
+
66
+ describe :on_leave do
67
+
68
+ before(:each) do
69
+ account.stub(:_test_callback_on_leave)
70
+ Account.on_leave :_test_callback_on_leave
71
+ end
72
+
73
+ it { account.should_receive(:_test_callback_on_leave) }
74
+
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
81
+ describe :lease! do
82
+
83
+ describe :after_create do
84
+
85
+ let(:account) { Account.new }
86
+
87
+ after(:each) { account.save }
88
+
89
+ it { account.should_receive(:lease!) }
90
+
91
+ end
92
+
93
+ describe :custom do
94
+
95
+ before(:each) do
96
+ account.stub(:_test_callback_before_lease)
97
+ account.stub(:_test_callback_after_lease)
98
+ Account.before_lease :_test_callback_before_lease
99
+ Account.after_lease :_test_callback_after_lease
100
+ end
101
+
102
+ after(:each) { account.lease! }
103
+
104
+ it { account.should_receive(:_test_callback_before_lease) }
105
+ it { account.should_receive(:_test_callback_after_lease) }
106
+
107
+ describe :aliases do
108
+
109
+ describe :on_lease do
110
+
111
+ before(:each) do
112
+ account.stub(:_test_callback_on_lease)
113
+ Account.on_lease :_test_callback_on_lease
114
+ end
115
+
116
+ it { account.should_receive(:_test_callback_on_lease) }
117
+
118
+ end
119
+
120
+ end
121
+
122
+ end
123
+
124
+ end
125
+
126
+ describe :break! do
127
+
128
+ describe :after_destroy do
129
+
130
+ after(:each) { account.destroy }
131
+
132
+ it { account.should_receive(:break!) }
133
+
134
+ end
135
+
136
+ describe :custom do
137
+
138
+ before(:each) do
139
+ account.stub(:_test_callback_before_break)
140
+ account.stub(:_test_callback_after_break)
141
+ Account.before_break :_test_callback_before_break
142
+ Account.after_break :_test_callback_after_break
143
+ end
144
+
145
+ after(:each) { account.break! }
146
+
147
+ it { account.should_receive(:_test_callback_before_break) }
148
+ it { account.should_receive(:_test_callback_after_break) }
149
+
150
+ describe :aliases do
151
+
152
+ describe :on_break do
153
+
154
+ before(:each) do
155
+ account.stub(:_test_callback_on_break)
156
+ Account.on_break :_test_callback_on_break
157
+ end
158
+
159
+ it { account.should_receive(:_test_callback_on_break) }
160
+
161
+ end
162
+
163
+ end
164
+
165
+ end
166
+
167
+ end
168
+
169
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe Leases::Model do
4
+
5
+ with_model :Account do
6
+ table do |t|
7
+ t.string :name
8
+ t.timestamps
9
+ end
10
+ end
11
+
12
+ describe :leases do
13
+
14
+ it { Account.respond_to?(:leases).should be_true }
15
+
16
+ it 'should set leases_options' do
17
+ Account.leases :name => :slug
18
+ Account.leases_options.should == { :name => :slug }
19
+ end
20
+
21
+ it 'should add the class to a list of leasers' do
22
+ Account.leases :name => :slug
23
+ Leases.leasers.should include 'Account'
24
+ end
25
+
26
+ end
27
+
28
+ describe :shared_by_leasers do
29
+
30
+ with_model :User do
31
+ table do |t|
32
+ t.string :name
33
+ t.timestamps
34
+ end
35
+ end
36
+
37
+ before(:each) { User.shared_by_leasers }
38
+
39
+ it { Apartment.excluded_models.should include 'User' }
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Leases do
4
+
5
+ with_model :Account do
6
+ table do |t|
7
+ t.string :name
8
+ t.timestamps
9
+ end
10
+ model do
11
+ leases
12
+ end
13
+ end
14
+
15
+ describe :leasing do
16
+
17
+ before(:each) { Leases.leasing(Account) }
18
+
19
+ it { Leases.leasers.should == ['Account'] }
20
+ it { Apartment.excluded_models.should include 'Account' }
21
+
22
+ end
23
+
24
+ describe :leaser_names do
25
+
26
+ let!(:account_1) { Account.create }
27
+ let!(:account_2) { Account.create }
28
+
29
+ it { Leases.leaser_names.should == [account_1.leaser_name, account_2.leaser_name] }
30
+ it { Apartment.database_names.should == Leases.leaser_names }
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,31 @@
1
+ require 'active_record'
2
+ require 'action_controller'
3
+
4
+ require 'leases'
5
+ require 'with_model'
6
+ require 'rspec/rails'
7
+
8
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3',
9
+ :database => File.dirname(__FILE__) + '/leaser.sqlite3')
10
+
11
+ Dir['spec/support/**/*.rb'].each { |f| load f }
12
+
13
+ RSpec.configure do |config|
14
+
15
+ config.mock_with :rspec
16
+ config.extend WithModel
17
+
18
+ config.before(:each) do
19
+ # Stub Apartment database interactions
20
+ Apartment::Database.stub(:switch)
21
+ Apartment::Database.stub(:reset)
22
+ Apartment::Database.stub(:create)
23
+ Apartment::Database.stub(:drop)
24
+ end
25
+
26
+ end
27
+
28
+ module Dummy
29
+ class Application < Rails::Application
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,205 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: leases
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Arjen Oosterkamp
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '2.3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '2.3'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec-rails
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '2.0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '2.0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: sqlite3
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: with_model
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rails
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '3.0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '3.0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: apartment
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0.20'
134
+ type: :runtime
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0.20'
142
+ description: Database multi-tenancy for Rails.
143
+ email:
144
+ - mail@arjen.me
145
+ executables: []
146
+ extensions: []
147
+ extra_rdoc_files: []
148
+ files:
149
+ - .gitignore
150
+ - .travis.yml
151
+ - Gemfile
152
+ - LICENSE.txt
153
+ - README.md
154
+ - Rakefile
155
+ - leases.gemspec
156
+ - lib/leases.rb
157
+ - lib/leases/controller.rb
158
+ - lib/leases/model.rb
159
+ - lib/leases/model/base.rb
160
+ - lib/leases/model/callbacks.rb
161
+ - lib/leases/railtie.rb
162
+ - lib/leases/version.rb
163
+ - spec/leases/controller_spec.rb
164
+ - spec/leases/model/base_spec.rb
165
+ - spec/leases/model/callbacks_spec.rb
166
+ - spec/leases/model_spec.rb
167
+ - spec/leases_spec.rb
168
+ - spec/spec_helper.rb
169
+ homepage: https://github.com/Arjeno/leases
170
+ licenses: []
171
+ post_install_message:
172
+ rdoc_options: []
173
+ require_paths:
174
+ - lib
175
+ required_ruby_version: !ruby/object:Gem::Requirement
176
+ none: false
177
+ requirements:
178
+ - - ! '>='
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ segments:
182
+ - 0
183
+ hash: -3059890359605888421
184
+ required_rubygems_version: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ! '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ segments:
191
+ - 0
192
+ hash: -3059890359605888421
193
+ requirements: []
194
+ rubyforge_project:
195
+ rubygems_version: 1.8.24
196
+ signing_key:
197
+ specification_version: 3
198
+ summary: Database multi-tenancy for Rails.
199
+ test_files:
200
+ - spec/leases/controller_spec.rb
201
+ - spec/leases/model/base_spec.rb
202
+ - spec/leases/model/callbacks_spec.rb
203
+ - spec/leases/model_spec.rb
204
+ - spec/leases_spec.rb
205
+ - spec/spec_helper.rb