mongoid-multitenancy 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mongoid-multitenancy.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,55 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ mongoid-multitenancy (0.1)
5
+ mongoid (~> 3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (3.2.9)
11
+ activesupport (= 3.2.9)
12
+ builder (~> 3.0.0)
13
+ activesupport (3.2.9)
14
+ i18n (~> 0.6)
15
+ multi_json (~> 1.0)
16
+ builder (3.0.4)
17
+ database_cleaner (0.9.1)
18
+ diff-lcs (1.1.3)
19
+ i18n (0.6.1)
20
+ mongoid (3.0.14)
21
+ activemodel (~> 3.1)
22
+ moped (~> 1.1)
23
+ origin (~> 1.0)
24
+ tzinfo (~> 0.3.22)
25
+ mongoid-rspec (1.5.5)
26
+ mongoid (>= 3.0.1)
27
+ rake
28
+ rspec (>= 2.9)
29
+ moped (1.3.1)
30
+ multi_json (1.5.0)
31
+ origin (1.0.11)
32
+ rake (10.0.3)
33
+ redcarpet (2.2.2)
34
+ rspec (2.12.0)
35
+ rspec-core (~> 2.12.0)
36
+ rspec-expectations (~> 2.12.0)
37
+ rspec-mocks (~> 2.12.0)
38
+ rspec-core (2.12.1)
39
+ rspec-expectations (2.12.0)
40
+ diff-lcs (~> 1.1.3)
41
+ rspec-mocks (2.12.0)
42
+ tzinfo (0.3.35)
43
+ yard (0.8.3)
44
+
45
+ PLATFORMS
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ database_cleaner (~> 0.9)
50
+ mongoid-multitenancy!
51
+ mongoid-rspec (~> 1.5)
52
+ rake (~> 10.0)
53
+ redcarpet (~> 2.2)
54
+ rspec (~> 2.12)
55
+ yard (~> 0.8)
data/LICENSE.TXT ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Perfect Memory
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,156 @@
1
+ # mongoid-multitenancy
2
+
3
+ mongoid-multitenancy adds the ability to scope [Mongoid](https://github.com/mongoid/mongoid) models to a tenant in a **shared database strategy**. Tenants are represented by a tenant model, such as `Client`. mongoid-multitenancy will help you set the current tenant on each request and ensures all 'tenant models' are always properly scoped to the current tenant: when viewing, searching and creating.
4
+
5
+ It is directly inspired by the [acts_as_tenant gem](https://github.com/ErwinM/acts_as_tenant) for Active Record.
6
+
7
+ In addition, mongoid-multitenancy:
8
+
9
+ * allows you to set the current tenant
10
+ * redefines some mongoid functions like `index`, `validates_with` and `delete_all` to take in account the multitenancy
11
+ * makes the tenant field immutable once it is persisted
12
+ * is thread safe.
13
+
14
+ Installation
15
+ ===============
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ gem 'mongoid_multitenancy'
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install mongoid_multitenancy
28
+
29
+ Usage
30
+ ===============
31
+
32
+ There are two steps in adding multi-tenancy to your app with acts_as_tenant:
33
+
34
+ 1. setting the current tenant and
35
+ 2. scoping your models.
36
+
37
+ Setting the current tenant
38
+ --------------------------
39
+ There are two ways to set the current tenant: (1) by setting the current tenant manually, or (2) by setting the current tenant for a block.
40
+
41
+ **Setting the current tenant in a controller, manually**
42
+
43
+ Mongoid::MultiTenancy.current_tenant = client_instance
44
+
45
+ Setting the current_tenant yourself requires you to use a before_filter to set the Mongoid::MultiTenancy.current_tenant variable.
46
+
47
+ **Setting the current tenant for a block**
48
+
49
+ Mongoid::MultiTenancy.with_tenant(client_instance) do
50
+ # Current tenant is set for all code in this block
51
+ end
52
+
53
+ This approach is useful when running background processes for a specified tenant. For example, by putting this in your worker's run method,
54
+ any code in this block will be scoped to the current tenant. All methods that set the current tenant are thread safe.
55
+
56
+ **Note:** If the current tenant is not set by one of these methods, mongoid-multitenancy will apply a global scope to your models, not related to any tenant. So make sure you use one of the two methods to tell mongoid-multitenancy about the current tenant.
57
+
58
+ Scoping your models
59
+ -------------------
60
+ class Client
61
+ include Mongoid::Document
62
+
63
+ field :name, :type => String
64
+ validates_uniqueness_of :name
65
+ end
66
+
67
+ class Article
68
+ include Mongoid::Document
69
+ include Mongoid::Multitenancy::Document
70
+
71
+ tenant(:client)
72
+
73
+ field :title, :type => String
74
+ end
75
+
76
+ Adding `tenant` to your model declaration will scope that model to the current tenant **BUT ONLY if a current tenant has been set**.
77
+ The association passed to the `tenant` function must be valid.
78
+
79
+ Some examples to illustrate this behavior:
80
+
81
+ # This manually sets the current tenant for testing purposes. In your app this is handled by the gem.
82
+ Mongoid::MultiTenancy.current_tenant = Client.find_by(:name => 'Perfect Memory') # => <#Client _id:50ca04b86c82bfc125000025, :name: "Perfect Memory">
83
+
84
+ # All searches are scoped by the tenant, the following searches will only return objects belonging to the current client.
85
+ Article.all # => all articles where client_id => 50ca04b86c82bfc125000025
86
+
87
+ # New objects are scoped to the current tenant
88
+ Article.new(:title => 'New blog') # => <#Article _id: nil, title: 'New blog', :client_id: 50ca04b86c82bfc125000025>
89
+
90
+ # It makes the tenant field immutable once it is persisted to avoid inconsistency
91
+ article.persited? # => true
92
+ article.client = another_client
93
+ article.valid? # => false
94
+
95
+ Rails
96
+ -------------------
97
+
98
+ If you are using Rails, you may want to set the current tenant at each request.
99
+
100
+ **Manually set the current tenant in ApplicationController using the host request**
101
+
102
+ class ApplicationController < ActionController::Base
103
+ before_filter :set_current_client
104
+
105
+ def set_current_client
106
+ current_client = Client.find_by_host(request.host)
107
+ Mongoid::MultiTenancy.current_tenant = current_client
108
+ end
109
+ end
110
+
111
+ Setting the current_tenant yourself requires you to use a before_filter to set the Mongoid::MultiTenancy.current_tenant variable.
112
+
113
+ Mongoid Uniqueness validators
114
+ -------------------
115
+
116
+ mongoid-multitenancy will automatically add the tenant foreign key in the scope list for each of uniqueness validators in order
117
+ to avoid to redefine all your validators.
118
+
119
+ class Article
120
+ include Mongoid::Document
121
+ include Mongoid::Multitenancy::Document
122
+
123
+ tenant(:client)
124
+
125
+ field :slug
126
+
127
+ validates_uniqueness_of :slug # => :scope => client_id is added automatically
128
+ end
129
+
130
+ Mongoid indexes
131
+ -------------------
132
+
133
+ mongoid-multitenancy will automatically add the tenant foreign key in all your mongoid indexes to avoid to redefine all your validators.
134
+
135
+ class Article
136
+ include Mongoid::Document
137
+ include Mongoid::Multitenancy::Document
138
+
139
+ tenant(:client)
140
+
141
+ field :title
142
+
143
+ index({ :title => 1 }) # => create an index with { :client_id => 1, :title => 1 }
144
+ end
145
+
146
+ Author & Credits
147
+ ----------------
148
+ mongoid-multitenancy is written by [Aymeric Brisse](https://github.com/abrisse/), from [Perfect Memory](http://www.perfect-memory.com).
149
+
150
+ ## Contributing
151
+
152
+ 1. Fork it
153
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
154
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
155
+ 4. Push to the branch (`git push origin my-new-feature`)
156
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'yard'
4
+
5
+ YARD::Rake::YardocTask.new
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
@@ -0,0 +1 @@
1
+ require 'mongoid/multitenancy'
@@ -0,0 +1,35 @@
1
+ module Mongoid
2
+ module Multitenancy
3
+ require "mongoid"
4
+
5
+ require "mongoid/multitenancy/document"
6
+ require "mongoid/multitenancy/version"
7
+
8
+ class << self
9
+
10
+ # Set the current tenant. Make it Thread aware
11
+ def current_tenant=(tenant)
12
+ Thread.current[:current_tenant] = tenant
13
+ end
14
+
15
+ # Returns the current tenant
16
+ def current_tenant
17
+ Thread.current[:current_tenant]
18
+ end
19
+
20
+ # Affects a tenant temporary for a block execution
21
+ def with_tenant(tenant, &block)
22
+ if block.nil?
23
+ raise ArgumentError, "block required"
24
+ end
25
+
26
+ old_tenant = self.current_tenant
27
+ self.current_tenant = tenant
28
+
29
+ block.call
30
+
31
+ self.current_tenant = old_tenant
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,64 @@
1
+ module Mongoid
2
+ module Multitenancy
3
+ module Document
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ private
8
+
9
+ # Check that the tenant foreign key field has not been changed once the object has been persisted
10
+ def check_tenant_immutability
11
+ self.errors.add(self.class.tenant_field, 'is immutable and cannot be updated' ) if changed.include?(self.class.tenant_field)
12
+ end
13
+ end
14
+
15
+ module ClassMethods
16
+ # Access to the tenant field
17
+ attr_reader :tenant_field
18
+
19
+ def tenant(association = :account)
20
+ # Setup the association between the class and the tenant class
21
+ # TODO: should index this association if no other indexes are defined => , index: true
22
+ belongs_to association
23
+
24
+ # Get the tenant model and its foreign key
25
+ fkey = reflect_on_association(association).foreign_key
26
+ @tenant_field = fkey
27
+
28
+ # Validates the presence of the association key
29
+ validates_presence_of fkey
30
+
31
+ # Set the current_tenant on newly created objects
32
+ after_initialize lambda { |m| m.send "#{association}=".to_sym, Multitenancy.current_tenant if Multitenancy.current_tenant ; true }
33
+
34
+ # Rewrite accessors to make tenant foreign_key/association immutable
35
+ validate :check_tenant_immutability, :unless => :new_record?
36
+
37
+ # Set the default_scope to scope to current tenant
38
+ default_scope lambda {
39
+ where(Multitenancy.current_tenant ? { self.tenant_field => Multitenancy.current_tenant.id } : nil)
40
+ }
41
+ end
42
+
43
+ # Redefine 'validates_with' to add the tenant scope when using a UniquenessValidator
44
+ def validates_with(*args, &block)
45
+ if args.first == Validations::UniquenessValidator
46
+ args.last[:scope] = Array(args.last[:scope]) << self.tenant_field
47
+ end
48
+ super(*args, &block)
49
+ end
50
+
51
+ # Redefine 'index' to include the tenant field in first position
52
+ def index(spec, options = nil)
53
+ spec = { self.tenant_field => 1 }.merge(spec)
54
+ super(spec, options)
55
+ end
56
+
57
+ # Redefine 'delete_all' to take in account the default scope
58
+ def delete_all(conditions = nil)
59
+ self.where(conditions).delete
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,5 @@
1
+ module Mongoid
2
+ module Multitenancy
3
+ VERSION = "0.1"
4
+ end
5
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/mongoid/multitenancy/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Aymeric Brisse"]
6
+ gem.email = ["aymeric.brisse@mperfect-memory.com"]
7
+ gem.description = %q{MultiTenancy with Mongoid}
8
+ gem.summary = %q{Support of a multi-tenant database with Mongoid}
9
+ gem.homepage = "https://github.com/PerfectMemory/mongoid-multitenancy"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "mongoid-multitenancy"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Mongoid::Multitenancy::VERSION
17
+
18
+ gem.add_dependency('mongoid', '~> 3')
19
+
20
+ gem.add_development_dependency('rake', '~> 10.0')
21
+ gem.add_development_dependency('rspec', '~> 2.12')
22
+ gem.add_development_dependency('yard', '~> 0.8')
23
+ gem.add_development_dependency('mongoid-rspec', '~> 1.5')
24
+ gem.add_development_dependency('database_cleaner', '~> 0.9')
25
+ gem.add_development_dependency('redcarpet', '~> 2.2')
26
+ end
@@ -0,0 +1,15 @@
1
+ class Article
2
+ include Mongoid::Document
3
+ include Mongoid::Multitenancy::Document
4
+
5
+ tenant(:client)
6
+
7
+ field :slug, :type => String
8
+ field :title, :type => String
9
+
10
+ validates_uniqueness_of :slug
11
+ validates_presence_of :slug
12
+ validates_presence_of :title
13
+
14
+ index({ :title => 1 })
15
+ end
@@ -0,0 +1,5 @@
1
+ class Client
2
+ include Mongoid::Document
3
+
4
+ field :name, :type => String
5
+ end
@@ -0,0 +1,109 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Multitenancy do
4
+ let(:client) { Client.create!(:name => "client") }
5
+ let(:another_client) { Client.create!(:name => "another client") }
6
+
7
+ before { Mongoid::Multitenancy.current_tenant = client }
8
+ after { Mongoid::Multitenancy.current_tenant = nil }
9
+
10
+ describe ".with_tenant" do
11
+ it "should change temporary the current tenant within the block" do
12
+ Mongoid::Multitenancy.with_tenant(another_client) do
13
+ Mongoid::Multitenancy.current_tenant.should == another_client
14
+ end
15
+ end
16
+
17
+ it "should have restored the current tenant after the block" do
18
+ Mongoid::Multitenancy.with_tenant(another_client) do ; end
19
+ Mongoid::Multitenancy.current_tenant.should == client
20
+ end
21
+ end
22
+ end
23
+
24
+ describe Article do
25
+ it { should belong_to(:client) }
26
+ it { should validate_presence_of(:client_id) }
27
+ it { should validate_uniqueness_of(:slug).scoped_to(:client_id) }
28
+ it { should have_index_for(:client_id => 1, :title => 1) }
29
+
30
+ let(:client) { Client.create!(:name => "client") }
31
+ let(:another_client) { Client.create!(:name => "another client") }
32
+
33
+ describe ".initialize" do
34
+ before { Mongoid::Multitenancy.current_tenant = client }
35
+ after { Mongoid::Multitenancy.current_tenant = nil }
36
+
37
+ it "should set the client field" do
38
+ Article.new.client.should eq client
39
+ end
40
+ end
41
+
42
+ describe ".default_scope" do
43
+ before {
44
+ Mongoid::Multitenancy.with_tenant(client) { @articleX = Article.create!(:title => "title X", :slug => "article-x") }
45
+ Mongoid::Multitenancy.with_tenant(another_client) { @articleY = Article.create!(:title => "title Y", :slug => "article-y") }
46
+ }
47
+
48
+ context "with a current tenant" do
49
+ before { Mongoid::Multitenancy.current_tenant = another_client }
50
+ after { Mongoid::Multitenancy.current_tenant = nil }
51
+
52
+ it "should filter on the current tenant" do
53
+ Article.all.to_a.should == [@articleY]
54
+ end
55
+ end
56
+
57
+ context "without a current tenant" do
58
+ before { Mongoid::Multitenancy.current_tenant = nil }
59
+
60
+ it "should not filter on any tenant" do
61
+ Article.all.to_a.should == [@articleX, @articleY]
62
+ end
63
+ end
64
+ end
65
+
66
+ describe "#valid?" do
67
+ before { Mongoid::Multitenancy.current_tenant = client }
68
+ after { Mongoid::Multitenancy.current_tenant = nil }
69
+
70
+ let(:article) { Article.create!(:title => "title X", :slug => "article-x") }
71
+
72
+ context "when the tenant has not changed" do
73
+ it 'should be valid' do
74
+ article.title = "title X (2)"
75
+ article.should be_valid
76
+ end
77
+ end
78
+
79
+ context "when the tenant has changed" do
80
+ it 'should be invalid' do
81
+ article.title = "title X (2)"
82
+ article.client = another_client
83
+ article.should_not be_valid
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ describe "#delete_all" do
90
+ before {
91
+ Mongoid::Multitenancy.with_tenant(client) { @articleX = Article.create!(:title => "title X", :slug => "article-x") }
92
+ Mongoid::Multitenancy.with_tenant(another_client) { @articleY = Article.create!(:title => "title Y", :slug => "article-y") }
93
+ }
94
+
95
+ context "with a current tenant" do
96
+ it "should only delete the current tenant articles" do
97
+ Mongoid::Multitenancy.with_tenant(another_client) { Article.delete_all }
98
+ Article.all.to_a == [@articleX]
99
+ end
100
+ end
101
+
102
+ context "without a current tenant" do
103
+ it "should delete all the articles" do
104
+ Article.delete_all
105
+ Article.all.to_a.should be_empty
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,38 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
3
+ MODELS = File.join(File.dirname(__FILE__), "models")
4
+
5
+ require 'rubygems'
6
+ require 'bundler/setup'
7
+
8
+ require 'rspec'
9
+ require 'mongoid'
10
+ require 'mongoid-multitenancy'
11
+ require 'database_cleaner'
12
+ require 'mongoid-rspec'
13
+
14
+ Dir["#{MODELS}/*.rb"].each { |f| require f }
15
+
16
+ Mongoid.configure do |config|
17
+ config.connect_to "mongoid_multitenancy"
18
+ end
19
+
20
+ Mongoid.logger = Logger.new($stdout)
21
+
22
+ DatabaseCleaner.orm = "mongoid"
23
+
24
+ RSpec.configure do |config|
25
+ config.include Mongoid::Matchers
26
+
27
+ config.before(:all) do
28
+ DatabaseCleaner.strategy = :truncation
29
+ end
30
+
31
+ config.before(:each) do
32
+ DatabaseCleaner.start
33
+ end
34
+
35
+ config.after(:each) do
36
+ DatabaseCleaner.clean
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,178 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid-multitenancy
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Aymeric Brisse
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mongoid
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3'
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: '10.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: '10.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.12'
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.12'
62
+ - !ruby/object:Gem::Dependency
63
+ name: yard
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '0.8'
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: '0.8'
78
+ - !ruby/object:Gem::Dependency
79
+ name: mongoid-rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '1.5'
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: '1.5'
94
+ - !ruby/object:Gem::Dependency
95
+ name: database_cleaner
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '0.9'
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.9'
110
+ - !ruby/object:Gem::Dependency
111
+ name: redcarpet
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '2.2'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '2.2'
126
+ description: MultiTenancy with Mongoid
127
+ email:
128
+ - aymeric.brisse@mperfect-memory.com
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - .gitignore
134
+ - .rspec
135
+ - Gemfile
136
+ - Gemfile.lock
137
+ - LICENSE.TXT
138
+ - README.md
139
+ - Rakefile
140
+ - lib/mongoid-multitenancy.rb
141
+ - lib/mongoid/multitenancy.rb
142
+ - lib/mongoid/multitenancy/document.rb
143
+ - lib/mongoid/multitenancy/version.rb
144
+ - mongoid-multitenancy.gemspec
145
+ - spec/models/article.rb
146
+ - spec/models/client.rb
147
+ - spec/mongoid-multitenancy_spec.rb
148
+ - spec/spec_helper.rb
149
+ homepage: https://github.com/PerfectMemory/mongoid-multitenancy
150
+ licenses: []
151
+ post_install_message:
152
+ rdoc_options: []
153
+ require_paths:
154
+ - lib
155
+ required_ruby_version: !ruby/object:Gem::Requirement
156
+ none: false
157
+ requirements:
158
+ - - ! '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ none: false
163
+ requirements:
164
+ - - ! '>='
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ requirements: []
168
+ rubyforge_project:
169
+ rubygems_version: 1.8.24
170
+ signing_key:
171
+ specification_version: 3
172
+ summary: Support of a multi-tenant database with Mongoid
173
+ test_files:
174
+ - spec/models/article.rb
175
+ - spec/models/client.rb
176
+ - spec/mongoid-multitenancy_spec.rb
177
+ - spec/spec_helper.rb
178
+ has_rdoc: