Load and merge application settings from YAML files.
At load time, settings are merged in two stages. First, all YAML data are recursively merged in reverse file order. Settings in succeeding files override all duplicate settings in preceding files. Second, the user selected settings—specified by key (e.g., environment key)—are recursively merged with the default settings.
This class can load multiple settings files, which provides a few benefits:
Confidential settings can be stored separately and securely from non-confidential settings; for example, in a public repository.
Settings for each application component or service (e.g., database, payment gateway, logger, CDN) can be stored in their respective files.
Shared or system-wide settings can be merged with application settings.
Settings File Examples
Absolute minimal settings
Above is the mandatory
default stanza, which
must be present in at least one of the YAML settings files, even if it is
empty. This isn't very useful, so lets add a couple of default
default: setting_1: on setting_2: off
Here we have settings that specify the database name, user, host, and
password file. There are three additional top-level stanzas:
These stanzas can be defined for any reason and have any name, but
typically represent the runtime environment or mode of the application.
Zero or more non-default top-level stanzas can be defined.
# database.yaml default: db: host: db.example.com user: dbusr pass: config/db-access development: db: name: myapp_dev production: db: name: myapp pass: /var/www/sites/myapp/db-access test: db: name: myapp_test
With these settings, the
default will always provide the
user because it is not
overridden in any other stanza. However, the database
not specified in
default because it is set in each
production, the database password file is
unique—and secure of course—thus overrides
First things first!
Load database settings
production using the database settings above. The
production settings are merged into
settings = .('database.yaml', :production) settings.db.host # => "db.example.com" settings.db.user # => "dbusr" settings.db.name # => "myapp" settings.db.pass # => "/var/www/sites/myapp/db-access"
The settings are accessed using methods. The
db setting is
actually a Hash and can also be accessed as such.
settings.db['host'] # => "db.example.com"
The difference is that method access raises an error if a setting is nonexistent.
settings.db.mia # KeyError: key not found: "mia" settings.db['mia'] # => nil
Method access is only available for string and symbol keys of Hash settings.
Load multiple settings files
It may be helpful to store settings for each application component separately. Or perhaps, settings are in a shared location. Here's how to initialize for such a situation:
settings = . '/etc/app-defaults.yml', # system wide '/etc/payment-gateway.yml', # system wide '/var/www/share/config/cdn.yml', # common for sites 'config/app.yml', # app specific 'config/database.yml', # app specific ENV['APP_MODE']
settings variable above is a compilation of four merges.
First, config/database.yml will merge with and override
config/app.yml; the result will merge with and override
cdn.yml; and so on. Therefore, specify files with more generic
- Ruby Gem
- Source Code
- Bug Tracker
First public release
Copyright © 2013-2017, Clint Pachl <[email protected]>
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.