Photo by Christin Hume on Unsplash
Lessons learned from failing to access an environment variable in YMAL file
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.