apartment 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/HISTORY.md +6 -0
- data/README.md +20 -2
- data/lib/apartment.rb +7 -1
- data/lib/apartment/adapters/abstract_adapter.rb +2 -1
- data/lib/apartment/adapters/postgresql_adapter.rb +17 -2
- data/lib/apartment/tenant.rb +2 -2
- data/lib/apartment/version.rb +1 -1
- data/spec/dummy/db/seeds/import.rb +5 -0
- data/spec/tenant_spec.rb +29 -0
- data/spec/unit/config_spec.rb +8 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9cdae6ddf14e715ae80d9c932ca1d6425e6f56e1
|
4
|
+
data.tar.gz: 8162a81d9eb38bf3992314a4d6fddad14bbc55a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8683c9692ee16ece0b1876937e2ad79d25c057106c1f750e077386f5c0d04e822b5318baf250b10bcb0f9918bbddabdde6a53aaddd9637e9de0ccb9f33748208
|
7
|
+
data.tar.gz: b76295e730aa02ac1f5a89b53459fed7499f70821bc0292321d2b2f7dc8fc036dc441995a25334f8207519102f5375063f6b99099902713db2c935f241e98238
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.
|
1
|
+
ruby-2.2
|
data/HISTORY.md
CHANGED
data/README.md
CHANGED
@@ -8,6 +8,19 @@ Apartment provides tools to help you deal with multiple tenants in your Rails
|
|
8
8
|
application. If you need to have certain data sequestered based on account or company,
|
9
9
|
but still allow some data to exist in a common tenant, Apartment can help.
|
10
10
|
|
11
|
+
## Excessive Memory Issues on ActiveRecord 4.x
|
12
|
+
|
13
|
+
> If you're noticing ever growing memory issues (ie growing with each tenant you add)
|
14
|
+
> when using Apartment, that's because there's [an issue](https://github.com/rails/rails/issues/19578)
|
15
|
+
> with how ActiveRecord maps Postgresql data types into AR data types.
|
16
|
+
> This has been patched and will be release for AR 4.2.2. It's apparently hard
|
17
|
+
> to backport to 4.1 unfortunately.
|
18
|
+
> If you want to use this today, you can use our [4.2.1 patched version](https://github.com/influitive/rails/tree/v4.2.1.memfix) on our github account using the code sample below.
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'rails', '4.2.1', github: 'influitive/rails', tag: 'v4.2.1.memfix'
|
22
|
+
```
|
23
|
+
|
11
24
|
|
12
25
|
## Installation
|
13
26
|
|
@@ -36,6 +49,9 @@ on a per-user basis, look under "Usage - Switching tenants per request", below.
|
|
36
49
|
> * for Rails 3.1.x: _Rails ~> 3.1.2_, it contains a [patch](https://github.com/rails/rails/pull/3232) that makes prepared statements work with multiple schemas
|
37
50
|
|
38
51
|
## Usage
|
52
|
+
### Video Tutorial
|
53
|
+
How to separate your application data into different accounts or companies.
|
54
|
+
[GoRails #47](https://gorails.com/episodes/multitenancy-with-apartment)
|
39
55
|
|
40
56
|
### Creating new Tenants
|
41
57
|
|
@@ -284,7 +300,7 @@ This would be for a config with `default_schema` set to `public` and `persistent
|
|
284
300
|
4. Next: `CREATE SCHEMA IF NOT EXISTS hstore;`
|
285
301
|
5. Finally: `CREATE EXTENSION IF NOT EXISTS hstore SCHEMA hstore;` and hit enter (`\q` to exit)
|
286
302
|
|
287
|
-
To double check, login to the console of your Heroku app and see if `Apartment.connection.
|
303
|
+
To double check, login to the console of your Heroku app and see if `Apartment.connection.schema_search_path` is `public,hstore`
|
288
304
|
|
289
305
|
#### 3. Ensure the schema is in the apartment config
|
290
306
|
```ruby
|
@@ -326,7 +342,7 @@ config.use_sql = true
|
|
326
342
|
|
327
343
|
### Managing Migrations
|
328
344
|
|
329
|
-
In order to migrate all of your tenants (or
|
345
|
+
In order to migrate all of your tenants (or postgresql schemas) you need to provide a list
|
330
346
|
of dbs to Apartment. You can make this dynamic by providing a Proc object to be called on migrations.
|
331
347
|
This object should yield an array of string representing each tenant name. Example:
|
332
348
|
|
@@ -378,3 +394,5 @@ config.prepend_environment = !Rails.env.production?
|
|
378
394
|
## License
|
379
395
|
|
380
396
|
Apartment is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
397
|
+
|
398
|
+
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/influitive/apartment/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
|
data/lib/apartment.rb
CHANGED
@@ -12,7 +12,7 @@ module Apartment
|
|
12
12
|
extend Forwardable
|
13
13
|
|
14
14
|
ACCESSOR_METHODS = [:use_schemas, :use_sql, :seed_after_create, :prepend_environment, :append_environment]
|
15
|
-
WRITER_METHODS = [:tenant_names, :database_schema_file, :excluded_models, :default_schema, :persistent_schemas, :connection_class, :tld_length, :db_migrate_tenants]
|
15
|
+
WRITER_METHODS = [:tenant_names, :database_schema_file, :excluded_models, :default_schema, :persistent_schemas, :connection_class, :tld_length, :db_migrate_tenants, :seed_data_file]
|
16
16
|
|
17
17
|
attr_accessor(*ACCESSOR_METHODS)
|
18
18
|
attr_writer(*WRITER_METHODS)
|
@@ -62,6 +62,12 @@ module Apartment
|
|
62
62
|
@database_schema_file = Rails.root.join('db', 'schema.rb')
|
63
63
|
end
|
64
64
|
|
65
|
+
def seed_data_file
|
66
|
+
return @seed_data_file if defined?(@seed_data_file)
|
67
|
+
|
68
|
+
@seed_data_file = "#{Rails.root}/db/seeds.rb"
|
69
|
+
end
|
70
|
+
|
65
71
|
def tld_length
|
66
72
|
@tld_length || 1
|
67
73
|
end
|
@@ -138,7 +138,8 @@ module Apartment
|
|
138
138
|
# Load the rails seed file into the db
|
139
139
|
#
|
140
140
|
def seed_data
|
141
|
-
|
141
|
+
# Don't log the output of seeding the db
|
142
|
+
silence_stream(STDOUT){ load_or_abort(Apartment.seed_data_file) } if Apartment.seed_data_file
|
142
143
|
end
|
143
144
|
alias_method :seed, :seed_data
|
144
145
|
|
@@ -157,7 +157,7 @@ module Apartment
|
|
157
157
|
|
158
158
|
# `pg_dump -s -x -O -n #{default_tenant} #{excluded_tables} #{dbname}`
|
159
159
|
|
160
|
-
`pg_dump -s -x -O -n #{default_tenant} #{dbname}`
|
160
|
+
with_pg_env { `pg_dump -s -x -O -n #{default_tenant} #{dbname}` }
|
161
161
|
end
|
162
162
|
|
163
163
|
# Dump data from schema_migrations table
|
@@ -165,7 +165,22 @@ module Apartment
|
|
165
165
|
# @return {String} raw SQL contaning inserts with data from schema_migrations
|
166
166
|
#
|
167
167
|
def pg_dump_schema_migrations_data
|
168
|
-
`pg_dump -a --inserts -t schema_migrations -n #{default_tenant} #{dbname}`
|
168
|
+
with_pg_env { `pg_dump -a --inserts -t schema_migrations -n #{default_tenant} #{dbname}` }
|
169
|
+
end
|
170
|
+
|
171
|
+
# Temporary set Postgresql related environment variables if there are in @config
|
172
|
+
#
|
173
|
+
def with_pg_env(&block)
|
174
|
+
pghost, pgport, pguser, pgpassword = ENV['PGHOST'], ENV['PGPORT'], ENV['PGUSER'], ENV['PGPASSWORD']
|
175
|
+
|
176
|
+
ENV['PGHOST'] = @config[:host] if @config[:host]
|
177
|
+
ENV['PGPORT'] = @config[:port].to_s if @config[:port]
|
178
|
+
ENV['PGUSER'] = @config[:username].to_s if @config[:username]
|
179
|
+
ENV['PGPASSWORD'] = @config[:password].to_s if @config[:password]
|
180
|
+
|
181
|
+
block.call
|
182
|
+
ensure
|
183
|
+
ENV['PGHOST'], ENV['PGPORT'], ENV['PGUSER'], ENV['PGPASSWORD'] = pghost, pgport, pguser, pgpassword
|
169
184
|
end
|
170
185
|
|
171
186
|
# Remove "SET search_path ..." line from SQL dump and prepend search_path set to current tenant
|
data/lib/apartment/tenant.rb
CHANGED
@@ -9,14 +9,14 @@ module Apartment
|
|
9
9
|
extend self
|
10
10
|
extend Forwardable
|
11
11
|
|
12
|
-
def_delegators :adapter, :create, :
|
12
|
+
def_delegators :adapter, :create, :drop, :switch, :switch!, :current, :each, :reset, :seed, :current_tenant, :default_tenant
|
13
13
|
|
14
14
|
attr_writer :config
|
15
15
|
|
16
16
|
# Initialize Apartment config options such as excluded_models
|
17
17
|
#
|
18
18
|
def init
|
19
|
-
process_excluded_models
|
19
|
+
adapter.process_excluded_models
|
20
20
|
end
|
21
21
|
|
22
22
|
# Fetch the proper multi-tenant adapter based on Rails config
|
data/lib/apartment/version.rb
CHANGED
data/spec/tenant_spec.rb
CHANGED
@@ -150,5 +150,34 @@ describe Apartment::Tenant do
|
|
150
150
|
end
|
151
151
|
end
|
152
152
|
end
|
153
|
+
|
154
|
+
context "seed paths" do
|
155
|
+
before do
|
156
|
+
Apartment.configure do |config|
|
157
|
+
config.excluded_models = []
|
158
|
+
config.use_schemas = true
|
159
|
+
config.seed_after_create = true
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
after{ subject.drop db1 }
|
164
|
+
|
165
|
+
it 'should seed from default path' do
|
166
|
+
subject.create db1
|
167
|
+
subject.switch! db1
|
168
|
+
User.count.should eq(3)
|
169
|
+
User.first.name.should eq('Some User 0')
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'should seed from custom path' do
|
173
|
+
Apartment.configure do |config|
|
174
|
+
config.seed_data_file = "#{Rails.root}/db/seeds/import.rb"
|
175
|
+
end
|
176
|
+
subject.create db1
|
177
|
+
subject.switch! db1
|
178
|
+
User.count.should eq(6)
|
179
|
+
User.first.name.should eq('Different User 0')
|
180
|
+
end
|
181
|
+
end
|
153
182
|
end
|
154
183
|
end
|
data/spec/unit/config_spec.rb
CHANGED
@@ -5,6 +5,7 @@ describe Apartment do
|
|
5
5
|
describe "#config" do
|
6
6
|
|
7
7
|
let(:excluded_models){ ["Company"] }
|
8
|
+
let(:seed_data_file_path){ "#{Rails.root}/db/seeds/import.rb" }
|
8
9
|
|
9
10
|
it "should yield the Apartment object" do
|
10
11
|
Apartment.configure do |config|
|
@@ -28,6 +29,13 @@ describe Apartment do
|
|
28
29
|
Apartment.use_schemas.should be false
|
29
30
|
end
|
30
31
|
|
32
|
+
it "should set seed_data_file" do
|
33
|
+
Apartment.configure do |config|
|
34
|
+
config.seed_data_file = seed_data_file_path
|
35
|
+
end
|
36
|
+
Apartment.seed_data_file.should eq(seed_data_file_path)
|
37
|
+
end
|
38
|
+
|
31
39
|
it "should set seed_after_create" do
|
32
40
|
Apartment.configure do |config|
|
33
41
|
config.excluded_models = []
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apartment
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Brunner
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-07-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -244,6 +244,7 @@ files:
|
|
244
244
|
- spec/dummy/db/migrate/20111202022214_create_table_books.rb
|
245
245
|
- spec/dummy/db/schema.rb
|
246
246
|
- spec/dummy/db/seeds.rb
|
247
|
+
- spec/dummy/db/seeds/import.rb
|
247
248
|
- spec/dummy/db/test.sqlite3
|
248
249
|
- spec/dummy/public/404.html
|
249
250
|
- spec/dummy/public/422.html
|
@@ -339,7 +340,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
339
340
|
version: '0'
|
340
341
|
requirements: []
|
341
342
|
rubyforge_project:
|
342
|
-
rubygems_version: 2.4.
|
343
|
+
rubygems_version: 2.4.5
|
343
344
|
signing_key:
|
344
345
|
specification_version: 4
|
345
346
|
summary: A Ruby gem for managing database multitenancy
|
@@ -378,6 +379,7 @@ test_files:
|
|
378
379
|
- spec/dummy/db/migrate/20111202022214_create_table_books.rb
|
379
380
|
- spec/dummy/db/schema.rb
|
380
381
|
- spec/dummy/db/seeds.rb
|
382
|
+
- spec/dummy/db/seeds/import.rb
|
381
383
|
- spec/dummy/db/test.sqlite3
|
382
384
|
- spec/dummy/public/404.html
|
383
385
|
- spec/dummy/public/422.html
|