Lessons learned from failing to access an environment variable in YMAL file

·

3 min read

Note: The following was tested with Ruby 2.6.6 / Rails 5.2.6.

Situation

I tried to add an environment variable in the application.yml file.

# config/application.yml

default:
  #...
  API_TOKEN: ABC123456

And I expected when executing ENV['API_TOKEN'] in Rails console, I would get ABC123456. But I got nil.

$ rails console
$ ENV['API_TOKEN']
#=> nil

To see if I can figure out what's going on, I tried to do something below.


Problem-solving process

  • If we edit any files which were used to start the application, like configs or initializers, the application needs to be restarted. So, I thought that reload! in Rails console might reload the new code and solve this problem. However, I got the nil result the same.

  • Next, I google the keyword: 'rails console nil ymal env'. Not a good keyword, but I got another important keyword: spring stop.

What's Spring?

Spring is a Rails application preloader. It speeds up development by keeping your application running in the background so you don't need to boot it every time you run a test, rake task or migration. (Source)

Spring's Feature

  • Totally automatic; no need to explicitly start and stop the background process

  • Reloads your application code on each run

  • Restarts your application when configs / initializers / gem dependencies are changed

What was the result I got in Rails console after executing spring stop ?

I succeeded in accessing the environment variable!

# In the terminal
$ spring stop
#=> Spring stopped.

$ rails console
$ ENV['API_TOKEN']
#=> ABC123456

So, why spring stop can solve this problem?

According to the Spring's README:

But if we edit any of the files which were used to start the application (configs, initializers, your gemfile), the application needs to be fully restarted. This happens automatically.

After I change the config file, Spring should re-run. That means Spring will reload the application code.

But the result seemed not as I expected. Even though I have changed the YAML file and restarted Rails console, but Spring didn't re-run automatically. I guessed that Spring saw that my YMAL file didn't change.

So, I stopped Spring running first and then re-ran it by restarting Rails console.

We can check out the following block:

$ spring stop
#=> Spring stopped.

$ bin/spring status
#=> Spring is not running.

$ rails console
#=> ...Running via Spring preloader in process 1182
#=> Loading development environment (Rails 5.2.6)
$ ENV['API_TOKEN']
#=> ABC123456
$ exit

$ bin/spring status
#=> Spring is running:

# 1171 spring server | backme | started 14 secs ago
# 1172 ruby -I /Users/yuchu/.rvm/rubies/ruby-2.6.6/lib/ruby/site_ruby/2.6.0 -I # /Users/yuchu/.rvm/gems/ruby-2.6.6/gems/spring-2.1.1/lib -e require 'spring/application/boot'

Rails console ran via Spring preloader and Spring started 14 secs ago. Spring has reloaded the application's newest code now.

I thought that was the exact reason why the environment variable ENV['API_TOKEN'] could be accessed successfully.


Reference