Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dotenv gem doesn't get variables in Rails 6 or Ruby 2.6.5

I was using the dotenv gem to store environmental variables for development in a secrets file. The gem is no longer pulling the variables after upgrading ruby and rails on my computer. To try and track down the cause, and after a while of trying different options, I ended up creating two identical applications with just two differences. The ruby and the rails versions. One app is able to pull the environmental variables, the other returns nil. Any suggestions?

My Setup

Working application has

ruby "2.5.0"
gem 'rails',        '~> 5.1.6'

Non-working app has

ruby "2.6.5"
gem 'rails',        '~> 6.0.0'

What I have tried so far

  • I read the information on the gem's site and tried adding Dotenv::Railtie.load to my config/application.rb file.
  • Also, I tried adding require: 'dotenv/rails-now' in my Gemfile in case it was because of another gem issue.
  • I added require 'dotenv/load' to the files needing the variables.
  • I added 'require dotenv/load' to various places in my config/application.rb file

Each change I did individually and used byebug to check in the terminal if the variable was loaded. And each time the variable was still nil.

Anything that I am missing? Any suggestions? Or should I switch to another gem? I hear that figaro may do the same thing, just never used it before. Thank you in advance for your help.

like image 272
Christopher Warrington Avatar asked Nov 06 '19 19:11

Christopher Warrington


People also ask

How do I pass an environment variable in Ruby?

To pass environment variables to Ruby, simply set that environment variable in the shell. This varies slightly between operating systems, but the concepts remain the same. To set an environment variable on the Windows command prompt, use the set command.

What is the .ENV from the Dotenv gem used for?

ENV is basically a hash so accessing your variables later on in your code is as easy as using the syntax: ENV['SECRET_NAME_GOES_HERE']. For example, if you're setting up your Rails app to use omniauth, you'd call the variable in your /config/initializers/omniauth. rb file.

How do I see environment variables in rails?

Use command ENV in rails console. That will return a hash of your environmental values you can access. Alternatively, you can access your environmental variables from your apps root path using the same command and the variables will be returned formatted.


1 Answers

Ok, I found a way to make it work. Not sure if my explanation below will explain why the gem dotenv doesn't work with Rails 6. But, there is a better way to do this now in the newest version of Rails.

Reference

I figured out this answer because of this blog post by Romil Mehta (Rails 6 adds support for multi environment credentials)

Background

It seems that since Rails 5.2, we have been able to store credentials instead of secrets. I did not know this and had continued to use the above-mentioned gem.

What Happens Now

So, at the creation of a new RoR app, a config\credentials.yml.enc file is created within your Rails app that is encrypted with the master key found in the config\master.key file. (NOTE: You should hide this file before your first git commit or any other version tracker you may use.)

There are many ways to edit the encrypted file to get your own variables added for development. The blog author used this rails console line as an example: EDITOR=vim rails credentials:edit. I prefer 'nano' as my editor, so I changed the console line to: EDITOR=nano rails credentials:edit.

The New Way

From the nano shell, the credentials.yml.enc file is decrypted and I can read it. I then added in the credentials stored in my secrets file, which I was trying to access throughout my app. Something like this:

oauth:   
   server_base_url: http://localhost:3000
   oauth_token: 123
   oauth_secret: 456

Before, in my application, I would reference one of the secret keys by just calling ENV['variable_name'] as in ENV['server_base_url'] or ENV['oauth_token'] and I would get the output of 'http://localhost:3000' or '123' respectively. Now, to do the same thing, I need to have the code: Rails.application.credentials.section_name[:variable_name], where the 'section_name' is 'oauth' in my list above, followed by three variable names. So, to reference the 'oauth_token' I would do: Rails.application.credentials.oauth[:oauth_token].

Once I changed all of my ENV calls to the Rails.application.credentials code, my app worked. It pulled the secret variables ('credentials' now) and had my sample app connect to the oauth server to authorize login.

Summary

Again, I am not sure how this explains why the gem 'dotenv' does not work in my new Ruby and Rails environments. But, if anyone else is having the same issue, here is a workaround for you! And as it is a feature of a RoR application, it is probably not a workaround, but the right way to code your app.

Happy Coding!

like image 56
Christopher Warrington Avatar answered Oct 03 '22 00:10

Christopher Warrington