V2.2: Configuration
As of 2.2 Hanami will automatically generate DB configuration for your application. You can suppress this with –skip-db
hanami new bookshelf --skip-db
The default posture is to share a single configuration for the whole application, however Slices support having their own separate config.
DB persistence is provided by a new provider called db. It is activated by the presence of a config/db directory in the root Application or Slice.
DATABASE_URL
The primary point of configuration for your database connection is the DATABASE_URL environment variable.
DATABASE_URL=postgres://localhost/bookshelf_development
DATABASE_URL=mysql2://user:password@localhost/bookshelf_dev
DATABASE_URL=sqlite://config/db/development.sqlite
For more detail on the syntax of the URLs, see ROM SQL: Connecting to a Database
Advanced Configuration
If all you need to do is define DATABASE_URL
, you don’t need to create any further configuration. However, there are cases where you may want to add Sequel or ROM plugins to your configuration.
This is achieved by creating config/providers/db.rb
Hanami.app.configure_provider :db do
config.gateway :default do |gw|
# In addition to putting it in the DATABASE_URL env
# variable, it can also be set in code here
gw.database_url = "postgres://localhost:5432/mydb"
# The default PostgreSQL configuration would look like this
gw.adapter :sql do |sql|
# ROM plugins are organized under the applicable component type
# this plugin is named 'instrumentation' and applies to ROM::Relation
sql.plugin relations: :instrumentation do |plugin|
# If the plugin defines a config object with more options
# you can yield it here and set the values
plugin.notifications = slice["notifications"]
end
# Not every plugin requires extra configuration
sql.plugin relations: :auto_restrictions
# Sequel extensions are registered with a single symbolic name
# sql.extension supports multiple arguments, and you can call it
# multiple times. We split these up into two simply for readability.
sql.extension :caller_logging, :error_sql, :sql_comments
sql.extension :pg_array, :pg_enum, :pg_json, :pg_range
end
end
end
By default you are adding to the defaults above, but you can tell Hanami to skip them if you wish.
gw.adapter :sql do |sql|
# skip everything
sql.skip_defaults
# skip ROM plugins
sql.skip_defaults :plugins
# skip Sequel extensions
sql.skip_defaults :extensions
end
More on Sequel Extensions
Slice Configuration
As Slices are designed to provide modular isolation of business domains, it’s likely that database isolation will also be desirable in some cases.
When configuring your slice database, instead of DATABASE_URL
, you will use the SLICE_NAME__DATABASE_URL
convention.
So, given the following slice definition:
module Main
class Slice < Hanami::Slice
end
end
You would define a MAIN__DATABASE_URL
environment variable and a slices/main/config/db
directory.
Slice configuration is hierarchical, so if you have database configuration in the parent it will be inherited by all child slices by default. You can opt out of this via the import_from_parent setting.
module Main
class Slice < Hanami::Slice
config.db.import_from_parent = false
end
end
Gateway Configuration
Isolating database connections per-slice is not a requirement. You may want to have multiple connections within a single slice, especially if you’re connecting to different kinds of datastores. ROM configurations have gateways that define independent database connections.
Consider the case of a database migration from MySQL to PostgreSQL. Doing this in a single step is highly risky, so it would be desirable to have connections to both for a period of time.
The simplest configuration may be done using the DATABASE_URL__GATEWAY
format:
DATABASE_URL=postgres://localhost:5432/bookshelf_development
DATABASE_URL__LEGACY=mysql://localhost:3306/legacy
This works in concert with Slice configuration, as well:
MAIN__DATABASE_URL__LEGACY=mysql://localhost:3306/legacy
Sometimes you will want additional connection options used when opening the connection. These may be added as query parameters on the DATABASE_URL:
DATABASE_URL__LEGACY=mysql://localhost:3306/legacy?max_connections=4
But as with Slice configuration, you can do more advanced things in code as well:
Hanami.app.configure_provider :db do
config.gateway :default do |gw|
gw.connection_options search_path: ['public', 'alt']
gw.adapter :sql do |sql|
sql.extension :my_custom_ext
end
end
config.gateway :legacy do |gw|
gw.connection_options max_connections: 4
gw.adapter :sql
end
end
More on Sequel connection options
Relations are assigned to the default gateway automatically, so if you are defining a Relation for an alternate, you need to configure that explicitly:
class Users < Hanami::DB::Relation
gateway :legacy
schema infer: true
end
Container Keys
Hanami exposes your database configuration through a series of container keys.
db.config
- Final ROM Configuration object
db.rom
- ROM instance for this slice
db.gateway
- Default DB Gateway
db.gateways.default
- Explicitly-named gateway
Any additional gateways that you have defined will be registered under the db.gateways
namespace.