Do a bang-up job managing your environment variables.
ENV! provides a thin wrapper around ENV to accomplish a few things:
- Provide a central place to specify all your app’s environment variables.
- Fail loudly and helpfully if any environment variables are missing.
- Prevent an application from starting up with missing environment variables. (This is especially helpful in environments like Heroku, as your app will continue running the old code until the server is configured for a new revision.)
Add this line to your application’s Gemfile:
gem 'env_bang'
Or for Rails apps, use env_bang-rails
instead for more convenience:
gem 'env_bang-rails'
And then execute:
$ bundle
First, configure your environment variables somewhere in your app’s
startup process. If you use the env_bang-rails gem, place this in config/env.rb
to load before application configuration.
Example configuration:
ENV!.config do
use :APP_HOST
use :RAILS_SECRET_TOKEN
use :STRIPE_SECRET_KEY
use :STRIPE_PUBLISHABLE_KEY
# ... etc.
end
Once a variable is specified with the use
method, access it with
ENV!['MY_VAR']
This will function just like accessing ENV
directly, except that it will require the variable
to have been specified, and be present in the current environment. If either of these conditions
is not met, a KeyError will be raised with an explanation of what needs to be configured.
For some variables, you’ll want to include a default value in your code, and allow each
environment to ommit the variable for default behaviors. You can accomplish this with the
:default
option:
ENV!.config do
# ...
use :MAIL_DELIVERY_METHOD, default: 'smtp'
# ...
end
When a new team member installs or deploys your project, they may run into a missing
environment variable error. Save them time by including documentation along with the error
that is raised. To accomplish this, provide a description (of any length) to the use
method:
ENV!.config do
use 'RAILS_SECRET_KEY_BASE',
'Generate a fresh one with `SecureRandom.urlsafe_base64(64)`; see http://guides.rubyonrails.org/security.html#session-storage'
end
Now if someone installs or deploys the app without setting the RAILS_SECRET_KEY_BASE variable, they will see these instructions immediately upon running the app.
ENV! can convert your environment variables for you, keeping that tedium out of your application
code. To specify a type, use the :class
option:
ENV!.config do
use :COPYRIGHT_YEAR, class: Integer
use :MEMCACHED_SERVERS, class: Array
use :MAIL_DELIVERY_METHOD, class: Symbol, default: :smtp
use :DEFAULT_FRACTION, class: Float
use :ENABLE_SOUNDTRACK, class: :boolean
use :PUPPETMASTERS, class: Hash
end
Note that arrays will be derived by splitting the value on commas (','). To get arrays
of a specific type of value, use the :of
option:
ENV!.config do
use :YEARS_OF_INTEREST, class: Array, of: Integer
end
Hashes are split on commas (',') and key:value pairs are delimited by colon (':'). To get hashes of a specific type of value, use the :of
option, and to use a different type for keys (default is Symbol
), use the :keys
option:
ENV!.config do
use :BIRTHDAYS, class: Hash, of: Integer, keys: String
end
If you don’t specify a :class
option for a variable, ENV! defaults to a special
type conversion called :StringUnlessFalsey
. This conversion returns a string, unless
the value is a "falsey" string ('false', 'no', 'off', '0', 'disable', or 'disabled').
To turn off this magic for one variable, pass in class: String
. To disable it globally,
set
ENV!.config do
default_class String
end
Suppose your app needs a special type conversion that doesn’t come with ENV_BANG. You can
implement the conversion yourself with the add_class
method in the ENV!.config
block.
For example, to convert one of your environment variables to type Set
, you could write
the following configuration:
# In your environment:
export NUMBER_SET=1,3,5,7,9
# In your env.rb configuration file:
require 'set'
ENV!.config do
add_class Set do |value, options|
Set.new self.Array(value, options || {})
end
use :NUMBER_SET, class: Set, of: Integer
end
# Somewhere in your application:
ENV!['NUMBER_SET']
#=> #<Set: {1, 3, 5, 7, 9}>
-
ENV! is simply a method that returns ENV_BANG. In certain contexts (like defining a class), the exclamation mark notation is not allowed, so we use an alias to get this shorthand.
-
Any method that can be run within an
ENV!.config
block can also be run as a method directly onENV!
. For instance, instead ofENV!.config do add_class Set do ... end use :NUMBER_SET, class: Set end
It would also work to run
ENV!.add_class Set do ... end ENV!.use :NUMBER_SET, class: Set
While the
config
block is designed to provide a cleaner configuration file, calling the methods directly can occasionally be handy, such as when trying things out in an IRB/Pry session.
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request