apartment 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +45 -4
  3. data/Appraisals +12 -9
  4. data/HISTORY.md +18 -0
  5. data/README.md +69 -42
  6. data/Rakefile +24 -5
  7. data/apartment.gemspec +6 -16
  8. data/docker-compose.yml +14 -0
  9. data/gemfiles/rails_4_0.gemfile +1 -1
  10. data/gemfiles/rails_4_1.gemfile +1 -1
  11. data/gemfiles/rails_4_2.gemfile +1 -1
  12. data/gemfiles/rails_5_0.gemfile +1 -1
  13. data/gemfiles/{rails_3_2.gemfile → rails_5_1.gemfile} +2 -3
  14. data/gemfiles/rails_master.gemfile +12 -0
  15. data/lib/apartment.rb +3 -25
  16. data/lib/apartment/adapters/abstract_adapter.rb +19 -44
  17. data/lib/apartment/adapters/postgresql_adapter.rb +17 -3
  18. data/lib/apartment/elevators/generic.rb +1 -20
  19. data/lib/apartment/elevators/subdomain.rb +15 -4
  20. data/lib/apartment/railtie.rb +5 -2
  21. data/lib/apartment/tenant.rb +0 -10
  22. data/lib/apartment/version.rb +1 -1
  23. data/lib/generators/apartment/install/templates/apartment.rb +13 -8
  24. data/lib/tasks/apartment.rake +2 -2
  25. data/spec/adapters/mysql2_adapter_spec.rb +8 -0
  26. data/spec/apartment_spec.rb +1 -5
  27. data/spec/dummy/config/application.rb +1 -1
  28. data/spec/dummy/config/database.yml.sample +3 -1
  29. data/spec/dummy/db/migrate/20110613152810_create_dummy_models.rb +2 -1
  30. data/spec/dummy/db/migrate/20111202022214_create_table_books.rb +2 -1
  31. data/spec/dummy_engine/config/initializers/apartment.rb +3 -3
  32. data/spec/examples/connection_adapter_examples.rb +8 -0
  33. data/spec/examples/generic_adapter_examples.rb +35 -17
  34. data/spec/examples/schema_adapter_examples.rb +8 -0
  35. data/spec/integration/query_caching_spec.rb +63 -23
  36. data/spec/spec_helper.rb +12 -0
  37. data/spec/tenant_spec.rb +10 -3
  38. data/spec/unit/config_spec.rb +0 -7
  39. data/spec/unit/elevators/subdomain_spec.rb +28 -8
  40. metadata +20 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: caa901bdacc4fbec1f520ec03a1571b4fed1c087
4
- data.tar.gz: 8c794d406def5147e36c94ee8f627178b84448fa
3
+ metadata.gz: b431585840ff2cba38b0280bc2a4ee7e6460a089
4
+ data.tar.gz: 3f7679220b8adcf6ad0f832c70d5d2ea82ccc3c6
5
5
  SHA512:
6
- metadata.gz: d75822a0b53d5d283f4c0989068f3528f0b5c27cd06b9c7ff3b56ceb5d8659e504229445ec73ef01300e14bf7b7d8eae61dcfc7c34d9e66b4f4dd921dedf1502
7
- data.tar.gz: 42b087cc0ee285e1da347bd72b3949e491215b1f268f3a88131b353eeb127020ba1295d16f3beaeceb4bbec9ed55db7fc0cd60386a5767f7e6e3c51dc4bf9996
6
+ metadata.gz: 2f41b445022a6ec41ba6a34f2cbc3d5a086be9495972f8e5af8ab557168a9e649c74d76299a5043739cd2048f2a625701eeb47ea702a70857b6c18bab54a7648
7
+ data.tar.gz: cf3fd76a826a36b3a7b0b4a51bf5d68dc34624a830ddc8a2e13d9e7a2f88cd03e5541c0d53863bccffb14f97cd81c5bdd131943cf5b1918495cc86a83a527e44
data/.travis.yml CHANGED
@@ -4,20 +4,61 @@ rvm:
4
4
  - 2.1.9
5
5
  - 2.2.4
6
6
  - 2.3.1
7
+ - 2.4.1
8
+ - ruby-head
7
9
  - jruby-9.0.5.0
10
+ - jruby-9.1.9.0
8
11
  gemfile:
9
- - gemfiles/rails_3_2.gemfile
10
12
  - gemfiles/rails_4_0.gemfile
11
13
  - gemfiles/rails_4_1.gemfile
12
14
  - gemfiles/rails_4_2.gemfile
15
+ - gemfiles/rails_5_0.gemfile
16
+ - gemfiles/rails_5_1.gemfile
17
+ - gemfiles/rails_master.gemfile
13
18
  bundler_args: --without local
14
19
  before_install:
15
20
  - gem install bundler -v '> 1.5.0'
16
21
  env:
17
22
  RUBY_GC_MALLOC_LIMIT: 90000000
18
- RUBY_FREE_MIN: 200000
23
+ RUBY_GC_HEAP_FREE_SLOTS: 200000
19
24
  matrix:
25
+ allow_failures:
26
+ - rvm: ruby-head
27
+ - gemfile: gemfiles/rails_master.gemfile
20
28
  exclude:
21
- - rvm: 2.2.0
22
- gemfile: gemfiles/rails_3_2.gemfile
29
+ - rvm: 2.0.0
30
+ gemfile: gemfiles/rails_5_0.gemfile
31
+ - rvm: 2.0.0
32
+ gemfile: gemfiles/rails_5_1.gemfile
33
+ - rvm: 2.0.0
34
+ gemfile: gemfiles/rails_master.gemfile
35
+ - rvm: 2.1.9
36
+ gemfile: gemfiles/rails_5_0.gemfile
37
+ - rvm: 2.1.9
38
+ gemfile: gemfiles/rails_5_1.gemfile
39
+ - rvm: 2.1.9
40
+ gemfile: gemfiles/rails_master.gemfile
41
+ - rvm: 2.4.1
42
+ gemfile: gemfiles/rails_4_0.gemfile
43
+ - rvm: 2.4.1
44
+ gemfile: gemfiles/rails_4_1.gemfile
45
+ - rvm: ruby-head
46
+ gemfile: gemfiles/rails_4_0.gemfile
47
+ - rvm: ruby-head
48
+ gemfile: gemfiles/rails_4_1.gemfile
49
+ - rvm: jruby-9.0.5.0
50
+ gemfile: gemfiles/rails_4_2.gemfile
51
+ - rvm: jruby-9.0.5.0
52
+ gemfile: gemfiles/rails_5_0.gemfile
53
+ - rvm: jruby-9.0.5.0
54
+ gemfile: gemfiles/rails_5_1.gemfile
55
+ - rvm: jruby-9.0.5.0
56
+ gemfile: gemfiles/rails_master.gemfile
57
+ - rvm: jruby-9.1.9.0
58
+ gemfile: gemfiles/rails_5_0.gemfile
59
+ - rvm: jruby-9.1.9.0
60
+ gemfile: gemfiles/rails_5_1.gemfile
61
+ - rvm: jruby-9.1.9.0
62
+ gemfile: gemfiles/rails_master.gemfile
23
63
  fast_finish: true
64
+ cache: bundler
data/Appraisals CHANGED
@@ -1,20 +1,23 @@
1
- appraise "rails-3-2" do
2
- gem "rails", "~> 3.2"
3
- gem "test-unit", "~> 3.0"
4
- end
5
-
6
1
  appraise "rails-4-0" do
7
- gem "rails", "~> 4.0"
2
+ gem "rails", "~> 4.0.0"
8
3
  end
9
4
 
10
5
  appraise "rails-4-1" do
11
- gem "rails", "~> 4.1"
6
+ gem "rails", "~> 4.1.0"
12
7
  end
13
8
 
14
9
  appraise "rails-4-2" do
15
- gem "rails", "~> 4.2"
10
+ gem "rails", "~> 4.2.0"
16
11
  end
17
12
 
18
13
  appraise "rails-5-0" do
19
- gem "rails", "~> 5.0"
14
+ gem "rails", "~> 5.0.0"
15
+ end
16
+
17
+ appraise "rails-5-1" do
18
+ gem "rails", "5.1.1"
19
+ end
20
+
21
+ appraise "rails-master" do
22
+ gem "rails", git: 'https://github.com/rails/rails.git'
20
23
  end
data/HISTORY.md CHANGED
@@ -1,3 +1,21 @@
1
+ # 2.0.0
2
+ * July 26, 2017
3
+
4
+ - Raise FileNotFound rather than abort when loading files [meganemura]
5
+ - Add 5.1 support with fixes for deprecations [meganemura]
6
+ - Fix tests for 5.x and a host of dev-friendly improvements [meganemura]
7
+ - Keep query cache config after switching databases [fernandomm]
8
+ - Pass constants not strings to middleware stack (Rails 5) [tzabaman]
9
+ - Remove deprecations from 1.0.0 [caironoleto]
10
+ - Replace `tld_length` configuration option with PublicSuffix gem for the
11
+ subdomain elevator [humancopy]
12
+ - Pass full config to create_database to allow :encoding/:collation/etc
13
+ [kakipo]
14
+ - Don't retain a connection during initialization [mikecmpbll]
15
+ - Fix database name escaping in drop_command [mikecmpbll]
16
+ - Skip initialization for assets:clean and assets:precompile tasks
17
+ [frank-west-iii]
18
+
1
19
  # 1.2.0
2
20
  * July 28, 2016
3
21
 
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Apartment
2
- [![Code Climate](https://codeclimate.com/github/influitive/apartment.png)](https://codeclimate.com/github/influitive/apartment)
3
- [![Build Status](https://secure.travis-ci.org/influitive/apartment.png?branch=development)](http://travis-ci.org/influitive/apartment)
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/apartment.svg)](https://badge.fury.io/rb/apartment)
4
+ [![Code Climate](https://codeclimate.com/github/influitive/apartment/badges/gpa.svg)](https://codeclimate.com/github/influitive/apartment)
5
+ [![Build Status](https://travis-ci.org/influitive/apartment.svg?branch=development)](https://travis-ci.org/influitive/apartment)
4
6
 
5
7
  *Multitenancy for Rails and ActiveRecord*
6
8
 
@@ -29,7 +31,6 @@ this poll, we'd greatly appreciated it.
29
31
  gem 'rails', '4.2.1', github: 'influitive/rails', tag: 'v4.2.1.memfix'
30
32
  ```
31
33
 
32
-
33
34
  ## Installation
34
35
 
35
36
  ### Rails
@@ -57,7 +58,9 @@ on a per-user basis, look under "Usage - Switching tenants per request", below.
57
58
  > * 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
58
59
 
59
60
  ## Usage
61
+
60
62
  ### Video Tutorial
63
+
61
64
  How to separate your application data into different accounts or companies.
62
65
  [GoRails #47](https://gorails.com/episodes/multitenancy-with-apartment)
63
66
 
@@ -103,6 +106,9 @@ tenant, call switch with no arguments.
103
106
  You can have Apartment route to the appropriate tenant by adding some Rack middleware.
104
107
  Apartment can support many different "Elevators" that can take care of this routing to your data.
105
108
 
109
+ **NOTE: when switching tenants per-request, keep in mind that the order of your Rack middleware is important.**
110
+ See the [Middleware Considerations](#middleware-considerations) section for more.
111
+
106
112
  The initializer above will generate the appropriate code for the Subdomain elevator
107
113
  by default. You can see this in `config/initializers/apartment.rb` after running
108
114
  that generator. If you're *not* using the generator, you can specify your
@@ -114,27 +120,19 @@ manually in your `application.rb` like so
114
120
  require 'apartment/elevators/subdomain' # or 'domain' or 'generic'
115
121
  ```
116
122
 
117
- **Switch on subdomain**
123
+ #### Switch on subdomain
124
+
118
125
  In house, we use the subdomain elevator, which analyzes the subdomain of the request and switches to a tenant schema of the same name. It can be used like so:
119
126
 
120
127
  ```ruby
121
128
  # application.rb
122
129
  module MyApplication
123
130
  class Application < Rails::Application
124
- config.middleware.use 'Apartment::Elevators::Subdomain'
131
+ config.middleware.use Apartment::Elevators::Subdomain
125
132
  end
126
133
  end
127
134
  ```
128
135
 
129
- By default, the subdomain elevator assumes that the parent domain consists of two segments, e.g. 'example.com'. If this isn't the case, you can adjust the `tld_length` (top level domain length) configuration variable, which defaults to 1. For example, if you are using 'localhost' in development:
130
- ```ruby
131
- # config/initializers/apartment.rb
132
- Apartment.configure do |config|
133
- ...
134
- config.tld_length = 0 if Rails.env == 'development'
135
- end
136
- ```
137
-
138
136
  If you want to exclude a domain, for example if you don't want your application to treat www like a subdomain, in an initializer in your application, you can set the following:
139
137
 
140
138
  ```ruby
@@ -144,14 +142,15 @@ Apartment::Elevators::Subdomain.excluded_subdomains = ['www']
144
142
 
145
143
  This functions much in the same way as Apartment.excluded_models. This example will prevent switching your tenant when the subdomain is www. Handy for subdomains like: "public", "www", and "admin" :)
146
144
 
147
- **Switch on first subdomain**
148
- To switch on the first subdomain, which analyzes the chain of subdomains of the request and switches to a tenant schema of the first name in the chain (e.g. owls.birds.animals.com would switch to "owl"). It can be used like so:
145
+ #### Switch on first subdomain
146
+
147
+ To switch on the first subdomain, which analyzes the chain of subdomains of the request and switches to a tenant schema of the first name in the chain (e.g. owls.birds.animals.com would switch to "owl"). It can be used like so:
149
148
 
150
149
  ```ruby
151
150
  # application.rb
152
151
  module MyApplication
153
152
  class Application < Rails::Application
154
- config.middleware.use 'Apartment::Elevators::FirstSubdomain'
153
+ config.middleware.use Apartment::Elevators::FirstSubdomain
155
154
  end
156
155
  end
157
156
  ```
@@ -163,41 +162,44 @@ If you want to exclude a domain, for example if you don't want your application
163
162
  Apartment::Elevators::FirstSubdomain.excluded_subdomains = ['www']
164
163
  ```
165
164
 
166
- This functions much in the same way as the Subdomain elevator.
165
+ This functions much in the same way as the Subdomain elevator. **NOTE:** in fact, at the time of this writing, the `Subdomain` and `FirstSubdomain` elevators both use the first subdomain ([#339](https://github.com/influitive/apartment/issues/339#issuecomment-235578610)). If you need to switch on larger parts of a Subdomain, consider using a Custom Elevator.
166
+
167
+ #### Switch on domain
167
168
 
168
- **Switch on domain**
169
169
  To switch based on full domain (excluding subdomains *ie 'www'* and top level domains *ie '.com'* ) use the following:
170
170
 
171
171
  ```ruby
172
172
  # application.rb
173
173
  module MyApplication
174
174
  class Application < Rails::Application
175
- config.middleware.use 'Apartment::Elevators::Domain'
175
+ config.middleware.use Apartment::Elevators::Domain
176
176
  end
177
177
  end
178
178
  ```
179
179
 
180
- **Switch on full host using a hash**
180
+ #### Switch on full host using a hash
181
+
181
182
  To switch based on full host with a hash to find corresponding tenant name use the following:
182
183
 
183
184
  ```ruby
184
185
  # application.rb
185
186
  module MyApplication
186
187
  class Application < Rails::Application
187
- config.middleware.use 'Apartment::Elevators::HostHash', {'example.com' => 'example_tenant'}
188
+ config.middleware.use Apartment::Elevators::HostHash, {'example.com' => 'example_tenant'}
188
189
  end
189
190
  end
190
191
  ```
191
192
 
192
- **Custom Elevator**
193
- A Generic Elevator exists that allows you to pass a `Proc` (or anything that responds to `call`) to the middleware. This Object will be passed in an `ActionDispatch::Request` object when called for you to do your magic. Apartment will use the return value of this proc to switch to the appropriate tenant. Use like so:
193
+ #### Custom Elevator
194
+
195
+ A Generic Elevator exists that allows you to pass a `Proc` (or anything that responds to `call`) to the middleware. This Object will be passed in an `ActionDispatch::Request` object when called for you to do your magic. Apartment will use the return value of this proc to switch to the appropriate tenant. Use like so:
194
196
 
195
197
  ```ruby
196
198
  # application.rb
197
199
  module MyApplication
198
200
  class Application < Rails::Application
199
201
  # Obviously not a contrived example
200
- config.middleware.use 'Apartment::Elevators::Generic', Proc.new { |request| request.host.reverse }
202
+ config.middleware.use Apartment::Elevators::Generic, Proc.new { |request| request.host.reverse }
201
203
  end
202
204
  end
203
205
  ```
@@ -225,6 +227,28 @@ class MyCustomElevator < Apartment::Elevators::Generic
225
227
  end
226
228
  ```
227
229
 
230
+ #### Middleware Considerations
231
+
232
+ In the examples above, we show the Apartment middleware being appended to the Rack stack with
233
+
234
+ ```ruby
235
+ Rails.application.config.middleware.use Apartment::Elevators::Subdomain
236
+ ```
237
+
238
+ By default, the Subdomain middleware switches into a Tenant based on the subdomain at the beginning of the request, and when the request is finished, it switches back to the "public" Tenant. This happens in the [Generic](https://github.com/influitive/apartment/blob/development/lib/apartment/elevators/generic.rb#L22) elevator, so all elevators that inherit from this elevator will operate as such.
239
+
240
+ It's also good to note that Apartment switches back to the "public" tenant any time an error is raised in your application.
241
+
242
+ This works okay for simple applications, but it's important to consider that you may want to maintain the "selected" tenant through different parts of the Rack application stack. For example, the [Devise](https://github.com/plataformatec/devise) gem adds the `Warden::Manager` middleware at the end of the stack in the examples above, our `Apartment::Elevators::Subdomain` middleware would come after it. Trouble is, Apartment resets the selected tenant after the request is finish, so some redirects (e.g. authentication) in Devise will be run in the context of the "public" tenant. The same issue would also effect a gem such as the [better_errors](https://github.com/charliesome/better_errors) gem which inserts a middleware quite early in the Rails middleware stack.
243
+
244
+ To resolve this issue, consider adding the Apartment middleware at a location in the Rack stack that makes sense for your needs, e.g.:
245
+
246
+ ```ruby
247
+ Rails.application.config.middleware.insert_before 'Warden::Manager', 'Apartment::Elevators::Subdomain'
248
+ ```
249
+
250
+ Now work done in the Warden middleware is wrapped in the `Apartment::Tenant.switch` context started in the Generic elevator.
251
+
228
252
  ### Dropping Tenants
229
253
 
230
254
  To drop tenants using Apartment, use the following command:
@@ -251,7 +275,7 @@ end
251
275
 
252
276
  ### Excluding models
253
277
 
254
- If you have some models that should always access the 'public' tenant, you can specify this by configuring Apartment using `Apartment.configure`. This will yield a config object for you. You can set excluded models like so:
278
+ If you have some models that should always access the 'public' tenant, you can specify this by configuring Apartment using `Apartment.configure`. This will yield a config object for you. You can set excluded models like so:
255
279
 
256
280
  ```ruby
257
281
  config.excluded_models = ["User", "Company"] # these models will not be multi-tenanted, but remain in the global (public) namespace
@@ -259,7 +283,7 @@ config.excluded_models = ["User", "Company"] # these models will not be m
259
283
 
260
284
  Note that a string representation of the model name is now the standard so that models are properly constantized when reloaded in development
261
285
 
262
- Rails will always access the 'public' tenant when accessing these models, but note that tables will be created in all schemas. This may not be ideal, but its done this way because otherwise rails wouldn't be able to properly generate the schema.rb file.
286
+ Rails will always access the 'public' tenant when accessing these models, but note that tables will be created in all schemas. This may not be ideal, but its done this way because otherwise rails wouldn't be able to properly generate the schema.rb file.
263
287
 
264
288
  > **NOTE - Many-To-Many Excluded Models:**
265
289
  > Since model exclusions must come from referencing a real ActiveRecord model, `has_and_belongs_to_many` is NOT supported. In order to achieve a many-to-many relationship for excluded models, you MUST use `has_many :through`. This way you can reference the join model in the excluded models configuration.
@@ -267,6 +291,7 @@ Rails will always access the 'public' tenant when accessing these models, but n
267
291
  ### Postgresql Schemas
268
292
 
269
293
  ## Providing a Different default_schema
294
+
270
295
  By default, ActiveRecord will use `"$user", public` as the default `schema_search_path`. This can be modified if you wish to use a different default schema be setting:
271
296
 
272
297
  ```ruby
@@ -276,14 +301,16 @@ config.default_schema = "some_other_schema"
276
301
  With that set, all excluded models will use this schema as the table name prefix instead of `public` and `reset` on `Apartment::Tenant` will return to this schema as well.
277
302
 
278
303
  ## Persistent Schemas
279
- Apartment will normally just switch the `schema_search_path` whole hog to the one passed in. This can lead to problems if you want other schemas to always be searched as well. Enter `persistent_schemas`. You can configure a list of other schemas that will always remain in the search path, while the default gets swapped out:
304
+
305
+ Apartment will normally just switch the `schema_search_path` whole hog to the one passed in. This can lead to problems if you want other schemas to always be searched as well. Enter `persistent_schemas`. You can configure a list of other schemas that will always remain in the search path, while the default gets swapped out:
280
306
 
281
307
  ```ruby
282
308
  config.persistent_schemas = ['some', 'other', 'schemas']
283
309
  ```
284
310
 
285
311
  ### Installing Extensions into Persistent Schemas
286
- Persistent Schemas have numerous useful applications. [Hstore](http://www.postgresql.org/docs/9.1/static/hstore.html), for instance, is a popular storage engine for Postgresql. In order to use extensions such as Hstore, you have to install it to a specific schema and have that always in the `schema_search_path`.
312
+
313
+ Persistent Schemas have numerous useful applications. [Hstore](http://www.postgresql.org/docs/9.1/static/hstore.html), for instance, is a popular storage engine for Postgresql. In order to use extensions such as Hstore, you have to install it to a specific schema and have that always in the `schema_search_path`.
287
314
 
288
315
  When using extensions, keep in mind:
289
316
  * Extensions can only be installed into one schema per database, so we will want to install it into a schema that is always available in the `schema_search_path`
@@ -306,7 +333,6 @@ When using extensions, keep in mind:
306
333
  # BEFORE db:migrate. #
307
334
  ##################################################
308
335
 
309
-
310
336
  namespace :db do
311
337
  desc 'Also create shared_extensions Schema'
312
338
  task :extensions => :environment do
@@ -330,7 +356,7 @@ end
330
356
 
331
357
  #### 2. Ensure the schema is in Rails' default connection
332
358
 
333
- Next, your `database.yml` file must mimic what you've set for your default and persistent schemas in Apartment. When you run migrations with Rails, it won't know about the extensions schema because Apartment isn't injected into the default connection, it's done on a per-request basis, therefore Rails doesn't know about `hstore` or `uuid-ossp` during migrations. To do so, add the following to your `database.yml` for all environments
359
+ Next, your `database.yml` file must mimic what you've set for your default and persistent schemas in Apartment. When you run migrations with Rails, it won't know about the extensions schema because Apartment isn't injected into the default connection, it's done on a per-request basis, therefore Rails doesn't know about `hstore` or `uuid-ossp` during migrations. To do so, add the following to your `database.yml` for all environments
334
360
 
335
361
  ```yaml
336
362
  # database.yml
@@ -351,6 +377,7 @@ This would be for a config with `default_schema` set to `public` and `persistent
351
377
  To double check, login to the console of your Heroku app and see if `Apartment.connection.schema_search_path` is `public,hstore`
352
378
 
353
379
  #### 3. Ensure the schema is in the apartment config
380
+
354
381
  ```ruby
355
382
  # config/initializers/apartment.rb
356
383
  ...
@@ -359,6 +386,7 @@ config.persistent_schemas = ['shared_extensions']
359
386
  ```
360
387
 
361
388
  #### Alternative: Creating schema by default
389
+
362
390
  Another way that we've successfully configured hstore for our applications is to add it into the
363
391
  postgresql template1 database so that every tenant that gets created has it by default.
364
392
 
@@ -377,7 +405,8 @@ also contain the tenanted tables, which is an open issue with no real milestone
377
405
  Happy to accept PR's on the matter.
378
406
 
379
407
  #### Alternative: Creating new schemas by using raw SQL dumps
380
- Apartment can be forced to use raw SQL dumps insted of `schema.rb` for creating new schemas. Use this when you are using some extra features in postgres that can't be respresented in `schema.rb`, like materialized views etc.
408
+
409
+ Apartment can be forced to use raw SQL dumps insted of `schema.rb` for creating new schemas. Use this when you are using some extra features in postgres that can't be represented in `schema.rb`, like materialized views etc.
381
410
 
382
411
  This only applies while using postgres adapter and `config.use_schemas` is set to `true`.
383
412
  (Note: this option doesn't use `db/structure.sql`, it creates SQL dump by executing `pg_dump`)
@@ -387,12 +416,11 @@ Enable this option with:
387
416
  config.use_sql = true
388
417
  ```
389
418
 
390
-
391
419
  ### Managing Migrations
392
420
 
393
421
  In order to migrate all of your tenants (or postgresql schemas) you need to provide a list
394
- of dbs to Apartment. You can make this dynamic by providing a Proc object to be called on migrations.
395
- This object should yield an array of string representing each tenant name. Example:
422
+ of dbs to Apartment. You can make this dynamic by providing a Proc object to be called on migrations.
423
+ This object should yield an array of string representing each tenant name. Example:
396
424
 
397
425
  ```ruby
398
426
  # Dynamically get tenant names to migrate
@@ -418,8 +446,8 @@ Note that you can disable the default migrating of all tenants with `db:migrate`
418
446
  ### Handling Environments
419
447
 
420
448
  By default, when not using postgresql schemas, Apartment will prepend the environment to the tenant name
421
- to ensure there is no conflict between your environments. This is mainly for the benefit of your development
422
- and test environments. If you wish to turn this option off in production, you could do something like:
449
+ to ensure there is no conflict between your environments. This is mainly for the benefit of your development
450
+ and test environments. If you wish to turn this option off in production, you could do something like:
423
451
 
424
452
  ```ruby
425
453
  config.prepend_environment = !Rails.env.production?
@@ -454,7 +482,8 @@ end
454
482
  ```
455
483
 
456
484
  ## Delayed::Job
457
- ### Has been removed... See apartment-sidekiq for a better backgrounding experience
485
+
486
+ Has been removed. See [apartment-sidekiq](https://github.com/influitive/apartment-sidekiq) for a better backgrounding experience.
458
487
 
459
488
  ## Contributing
460
489
 
@@ -462,13 +491,11 @@ end
462
491
  * Copy them into the same directory but with the name `database.yml`
463
492
  * Edit them to fit your own settings
464
493
  * Rake tasks (see the Rakefile) will help you setup your dbs necessary to run tests
465
- * Please issue pull requests to the `development` branch. All development happens here, master is used for releases
466
- * Ensure that your code is accompanied with tests. No code will be merged without tests
494
+ * Please issue pull requests to the `development` branch. All development happens here, master is used for releases.
495
+ * Ensure that your code is accompanied with tests. No code will be merged without tests
467
496
 
468
497
  * If you're looking to help, check out the TODO file for some upcoming changes I'd like to implement in Apartment.
469
498
 
470
499
  ## License
471
500
 
472
501
  Apartment is released under the [MIT License](http://www.opensource.org/licenses/MIT).
473
-
474
- [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/influitive/apartment/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ require "rspec/core/rake_task"
9
9
 
10
10
  RSpec::Core::RakeTask.new(:spec => %w{ db:copy_credentials db:test:prepare }) do |spec|
11
11
  spec.pattern = "spec/**/*_spec.rb"
12
- # spec.rspec_opts = '--order rand:16996'
12
+ # spec.rspec_opts = '--order rand:47078'
13
13
  end
14
14
 
15
15
  namespace :spec do
@@ -51,7 +51,13 @@ namespace :postgres do
51
51
 
52
52
  desc 'Build the PostgreSQL test databases'
53
53
  task :build_db do
54
- %x{ createdb -E UTF8 #{pg_config['database']} -U#{pg_config['username']} } rescue "test db already exists"
54
+ params = []
55
+ params << "-E UTF8"
56
+ params << pg_config['database']
57
+ params << "-U#{pg_config['username']}"
58
+ params << "-h#{pg_config['host']}" if pg_config['host']
59
+ params << "-p#{pg_config['port']}" if pg_config['port']
60
+ %x{ createdb #{params.join(' ')} } rescue "test db already exists"
55
61
  ActiveRecord::Base.establish_connection pg_config
56
62
  ActiveRecord::Migrator.migrate('spec/dummy/db/migrate')
57
63
  end
@@ -59,7 +65,12 @@ namespace :postgres do
59
65
  desc "drop the PostgreSQL test database"
60
66
  task :drop_db do
61
67
  puts "dropping database #{pg_config['database']}"
62
- %x{ dropdb #{pg_config['database']} -U#{pg_config['username']} }
68
+ params = []
69
+ params << pg_config['database']
70
+ params << "-U#{pg_config['username']}"
71
+ params << "-h#{pg_config['host']}" if pg_config['host']
72
+ params << "-p#{pg_config['port']}" if pg_config['port']
73
+ %x{ dropdb #{params.join(' ')} }
63
74
  end
64
75
 
65
76
  end
@@ -70,7 +81,11 @@ namespace :mysql do
70
81
 
71
82
  desc 'Build the MySQL test databases'
72
83
  task :build_db do
73
- %x{ mysqladmin -u #{my_config['username']} --password=#{my_config['password']} create #{my_config['database']} } rescue "test db already exists"
84
+ params = []
85
+ params << "-h #{my_config['host']}" if my_config['host']
86
+ params << "-u #{my_config['username']}" if my_config['username']
87
+ params << "-p#{my_config['password']}" if my_config['password']
88
+ %x{ mysqladmin #{params.join(' ')} create #{my_config['database']} } rescue "test db already exists"
74
89
  ActiveRecord::Base.establish_connection my_config
75
90
  ActiveRecord::Migrator.migrate('spec/dummy/db/migrate')
76
91
  end
@@ -78,7 +93,11 @@ namespace :mysql do
78
93
  desc "drop the MySQL test database"
79
94
  task :drop_db do
80
95
  puts "dropping database #{my_config['database']}"
81
- %x{ mysqladmin -u #{my_config['username']} --password=#{my_config['password']} drop #{my_config['database']} --force}
96
+ params = []
97
+ params << "-h #{my_config['host']}" if my_config['host']
98
+ params << "-u #{my_config['username']}" if my_config['username']
99
+ params << "-p#{my_config['password']}" if my_config['password']
100
+ %x{ mysqladmin #{params.join(' ')} drop #{my_config['database']} --force}
82
101
  end
83
102
 
84
103
  end