In your Rails app, do you use ENV
or Rails.application.credentials
? Is there an easy way to use both? Lets find out.
I've been a long time fan of Figaro, a great gem that lets your store your environment variables in /config/application.yml
. I've used it in most of my Rails apps for two reasons. One, it lets you easily define variables for your for development
, staging
, production
environments. Two, it works well with Heroku since they also use ENV
for storing and accessing environment variables, so things work the same locally while developing as well as after it's been deployed. However the downside with Figaro is that all your environment variables are exposed to the outside world, which is problematic if your repo is open source.
Rails.application.credentials helps solve this problem by encrypting your environment variables in config/credentials.yml.enc
so they are only readable with the key providing a secure way to store them. However the downside, is your environment variables are now stored and accessed in two different ways, using Rails.application.credentials
and ENV
if you are also using Heroku.
It would be a lot more convenient, if you could define your variables in Rails.application.credentials
so they are encrypted and secure, yet still access them using ENV
so both local and remote environment variables are consistent.
You can do this easily by adding the following into /config/application.rb
.
credentials.config.each do |key, value|
if key.to_s == Rails.env
value.each do |env_key, env_value|
ENV[env_key.to_s.upcase] = env_value.to_s if ENV[env_key.to_s.upcase].blank?
ENV[env_key.to_s.downcase] = env_value.to_s if ENV[env_key.to_s.downcase].blank?
end
elsif ['development', 'staging', 'test', 'production'].include?(key.to_s) == false
ENV[key.to_s.upcase] = value.to_s if ENV[key.to_s.upcase].blank?
ENV[key.to_s.downcase] = value.to_s if ENV[key.to_s.downcase].blank?
end
end
Now you have the best of both worlds, security plus accessibility. You can now access all your environment variables via ENV
whether they are defined in Heroku or in Rails.application.credentials
.
ENV['HEROKU_APP_NAME'] # access Heroku defined variables
ENV['GITHUB_API_KEY'] # access variables from your credentials
ENV['git_api_key'] # also access variables in lowercase
ENV['rails_env_key'] # access environment specific variables
The snippet only sets the ENV
if it's not already defined. It also handles global or environment specific variables in your Rails.application.credentials
.
You can copy and paste the initializer above, or you can run the following template to add it to your project.
rails app:template LOCATION="https://railsbytes.com/script/Vp7s90"
Top comments (0)