README.md in apartment-0.26.1 vs README.md in apartment-1.0.0
- old
+ new
@@ -29,11 +29,11 @@
Configure as needed using the docs below.
That's all you need to set up the Apartment libraries. If you want to switch tenants
on a per-user basis, look under "Usage - Switching tenants per request", below.
-> NOTE: If using [postgresl schemas](http://www.postgresql.org/docs/9.0/static/ddl-schemas.html) you must use:
+> NOTE: If using [postgresql schemas](http://www.postgresql.org/docs/9.0/static/ddl-schemas.html) you must use:
>
> * 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
## Usage
@@ -65,11 +65,11 @@
### Switching Tenants
To switch tenants using Apartment, use the following command:
```ruby
-Apartment::Tenant.switch('tenant_name')
+Apartment::Tenant.switch!('tenant_name')
```
When switch is called, all requests coming to ActiveRecord will be routed to the tenant
you specify (with the exception of excluded models, see below). To return to the 'root'
tenant, call switch with no arguments.
@@ -146,10 +146,33 @@
config.middleware.use 'Apartment::Elevators::Generic', Proc.new { |request| request.host.reverse }
end
end
```
+Your other option is to subclass the Generic elevator and implement your own
+switching mechanism. This is exactly how the other elevators work. Look at
+the `subdomain.rb` elevator to get an idea of how this should work. Basically
+all you need to do is subclass the generic elevator and implement your own
+`parse_tenant_name` method that will ultimately return the name of the tenant
+based on the request being made. It *could* look something like this:
+
+```ruby
+# app/middleware/my_custom_elevator.rb
+class MyCustomElevator < Apartment::Elevators::Generic
+
+ # @return {String} - The tenant to switch to
+ def parse_tenant_name(request)
+ # request is an instance of Rack::Request
+
+ # example: look up some tenant from the db based on this request
+ tenant_name = SomeModel.from_request(request)
+
+ return tenant_name
+ end
+end
+```
+
## Config
The following config options should be set up in a Rails initializer such as:
config/initializers/apartment.rb
@@ -194,16 +217,16 @@
```ruby
config.persistent_schemas = ['some', 'other', 'schemas']
```
### Installing Extensions into Persistent Schemas
-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`.
+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`.
When using extensions, keep in mind:
* 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`
-* The schema and extension need to be created in the database *before* they are referenced in migrations, database.yml or apartment.
-* There does not seem to be a way to create the schema and extension using standard rails migrations.
+* The schema and extension need to be created in the database *before* they are referenced in migrations, database.yml or apartment.
+* There does not seem to be a way to create the schema and extension using standard rails migrations.
* Rails db:test:prepare deletes and recreates the database, so it needs to be easy for the extension schema to be recreated here.
#### 1. Ensure the extensions schema is created when the database is created
```ruby
@@ -241,20 +264,20 @@
end
```
#### 2. Ensure the schema is in Rails' default connection
-Next, your `database.yml` file must mimic what you've set for your default and persistent schemas in Apartment. When you run migrataions 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
+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
```yaml
# database.yml
...
adapter: postgresql
schema_search_path: "public,shared_extensions"
...
```
-This would be for a config with `default_schema` set to `public` and `persistent_schemas` set to `['shared_extensions']`. **Note**: This only works on Heroku with [Rails 4.1+](https://devcenter.heroku.com/changelog-items/427). For apps that use older Rails versions hosted on Heroku, the only way to properly setup is to start with a fresh PostgreSQL instance:
+This would be for a config with `default_schema` set to `public` and `persistent_schemas` set to `['shared_extensions']`. **Note**: This only works on Heroku with [Rails 4.1+](https://devcenter.heroku.com/changelog-items/426). For apps that use older Rails versions hosted on Heroku, the only way to properly setup is to start with a fresh PostgreSQL instance:
1. Append `?schema_search_path=public,hstore` to your `DATABASE_URL` environment variable, by this you don't have to revise the `database.yml` file (which is impossible since Heroku regenerates a completely different and immutable `database.yml` of its own on each deploy)
2. Run `heroku pg:psql` from your command line
3. And then `DROP EXTENSION hstore;` (**Note:** This will drop all columns that use `hstore` type, so proceed with caution; only do this with a fresh PostgreSQL instance)
4. Next: `CREATE SCHEMA IF NOT EXISTS hstore;`