I am using gem 'dotenv-rails', '~> 0.9.0' to load environment variables into a Rails 4.0.5 app. I have a .env file along with a .env.test. All is working well in development, however when it comes to testing, which I do with rspec, it is failing to set the environment variables.
I have gone into Rails console in testing environment and I can see they are set to nil.
Any tips on how to get dotenv to load in testing?
This is a late answer, but for anyone who may find it helpful, add this to spec_helper.rb
require 'dotenv'
Dotenv.load('.env')
Also, Dotenv.load can accept a list, for example:
Dotenv.load(
'.env.local',
'.env.test',
'.env'
)
If you have test specific environemnt config, You can use Dotenv.overload to overwrite other env config. Just add the following to your spec_helper.rb or rails_helper.rb.
require "dotenv"
Dotenv.overload ".env.test"
Dotenv.overload ".env.test.local"
Dotenv.load(File.expand_path("../../.env.#{Rails.env}", __FILE__))
upon researching Paritosh's answer I found that the file needed to specified per environment.
put this line in Dotenv::Railtie.load in rspec setting or any page in which you want to load dot env file.
Related
I am facing issue while loading envrionment variable in boot.rb. I tried with 2 gems dotenv & dotenv-rails but none of them worked for me. Other places I am able to use environment variable but not in boot.rb. Anyone have any clue on this one
if ["development"].include?(ENV['RAILS_ENV'])
require 'bootsnap/setup'
Bootsnap.setup(
cache_dir: 'tmp/cache', # Path to your cache
development_mode: 'development', # Current working environment, e.g. RACK_ENV, RAILS_ENV, etc
load_path_cache: true, # Optimize the LOAD_PATH with a cache
autoload_paths_cache: true, # Optimize ActiveSupport autoloads with cache
compile_cache_iseq: true, # Compile Ruby code into ISeq cache, breaks coverage reporting.
compile_cache_yaml: true # Compile YAML into a cache
)
end
DotEnv will only load your .env file into env once the Gem has been loaded.
In Rails this is done by the line Bundler.require(*Rails.groups) in config/application.rb. If you need to access the env vars before that you need to manually call Dotenv::Railtie.load:
Bundler.require(*Rails.groups)
Dotenv::Railtie.load
Or at least thats what the readme would lead you to belive. Instead of the Railtie I guess you could use the plain ruby approach:
require 'dotenv'
Dotenv.load
But there are tons options to set ENV vars from a file such as direnv which is not a Ruby gem and hooks into your shell itself.
You could use - depending on your needs - a load or require to explicitly process your .env file, before testing the environment variable.
gem 'dotenv-rails' is required in gemfile test and development environments.
.env file is saved in root
I believe variables use correct syntax; USERNAME=username
I am using Rails 5.0.4
I have not required 'dotenv-rails' anywhere, as the docs do not suggest that I need to.
When playing in the console, the only way I can access the variables is by calling, Dotenv.load in each session. Suggesting that Dotenv.load should be called somewhere in config of my app.
Add Dotenv::Railtie.load to your config/application.rb
You may also need to restart Spring.
bin/spring stop
It will restart once you run another rails command.
In case this helps anyone else:
This happened to me once. As it turns out, I was mistakenly passing RAILS_ENV=production in the environment variables, disabling it.
For me the bin/spring stop fixed the issue and I am using ruby 3.1.2 and rails 7.0.4.
In my config\environments\development.rb and config\environments\production.rb files, I set some global variables. In the example below, I have a a Redis instance that points to our cache, and a Statsd instance that points to the DataDog agent.
config.x.cache = Redis.new(url: ENV["CACHE"])
config.x.statsd = Statsd.new('localhost', 8125)
In the case of Redis, I added gem 'redis' to my gem file, ran bundle install and everything worked fine. In the case of StatsD, however, it seems that I need to also add require 'statsd' at the top of the development.rb and production.rb files in order to be able to create the instance. Of course, I also added gem 'dogstatsd-ruby' to my gem file and ran bundle install, but that didn't seem to be enough. If I don't add the require statement at the top of the config files, I get the following error when I try to run my Rails app:
uninitialized constant Statsd (NameError)
Can anyone explain why I have to add the require statement only in this particular case (StatsD), or is there is a better way to do this? Thanks!
I am using the default test for different purposes and I have decided to make a specific rspec environment configuration for running the test suite.
However, I discovered that upon changing to ENV["RAILS_ENV"] ||= rspec in my rails_helper.rb file, suddenly a LOT of things are going wrong, constants are not being loaded (FactoryGirl, DatabaseCleaner, etc. throw uninitialized constant errors)
My question is, where is the code that loads those guys in test environment ? Since I am planning to use this stage for other purposes than running automatic tests, I'm afraid this "out of nowhere" added configuration might not work well with what I am planning to do.
From the perspective of Rails, the test environment is configured and loaded like any other environment such as production or development. You can see this prefixing RAILS_ENV=test to many of the native Rails commands e.g. RAILS_ENV=test rails c will load the rails console for the test environment, and so on. Similarly, all test-specific configuration within Rails is defined in test.rb in your config/environments folder.
However, when you run your specs with rspec spec, you're actually starting the RSpec runner, which, for most intents and purposes, runs independently of Rails (even with the rspec-rails gem).
By convention, when RSpec starts the first thing it does is read command line args from the .rspec in the current directory, if it exists. Then it runs spec_helper.rb (and also rails_helper.rb for rspec-rails 3+). It's actually the spec_helper.rb which does all the heavy-lifting in loading the Rails environment for your tests, along with any of the modules you're using in tests, such as DatabaseCleaner, FactoryGirl, etc.
If you're wondering how RSpec hooks into Rails, the bulk of it is performed in this line, which bootstraps Rails.
require File.expand_path('../../config/environment', __FILE__)
Now, as to your question, without the ENV['RAILS_ENV'] ||= 'test' statement, the above line will load Rails in the default environment (development), which isn't what you want, since any gems not in the :test group will not be loaded, and environments/test.rb will not be loaded either.
TL;DR
Test configuration is handled by two files: spec/spec_helper.rb (sometimes named rails_helper.rb) and config/environments/test.rb. The former configures RSpec and any objects and modules which will be used specifically within the files used in spec, the latter configures your Rails app itself. Omitting ENV['RAILS_ENV'] ||= test loads the development environment and gemsets instead of the test environment and gemsets, which is why you're getting a ton of errors.
If you are getting uninitialized constant errors for FactoryGirl, DatabaseCleaner etc, you most likely included them to test group in your Gemfile.
You should move them to rspec group, eg:
# Gemfile
group :rspec do
gem 'factory_girl_rails', '~> 4.0'
gem 'faker'
end
I've a .env file in my root folder in production. This file defines SECRET_KEY_BASE which is used in config/secrets.yml. The problem is that I can't manage to load my .env file before my config/secrets.yml. I've tried using the dotenv gem without success.
Any idea on how todo this in production?
I don't want to set it globally for my webmaster user on the production server. The SECRET_KEY_BASE value should only be accessable for by application.
I'm using rails 4.1.
I too use dotenv gem. It works for me in almost all case.
This is my configuration of dotenv gem (yes, i put dotenv in Gemfile). I just create an aaaaa.rb initializer file.
config/initializers/aaaaaa.rb
#obscure name because rails load initializers/* files based on alphabets
require 'dotenv'
Dotenv.load
And, cases which it doesn't, i do this this finally in config/boot.rb file
ENV["SECRET_KEY_BASE"] = "foobar"
I was also having this problem. Here is how I got it to work. I followed documentation to initialize dotenv early:
# config/application.rb
Bundler.require(*Rails.groups)
Dotenv::Railtie.load
HOSTNAME = ENV['HOSTNAME']
But then I came across this error (issue #155):
gems/dotenv-rails-1.0.2/lib/dotenv/rails.rb:17:in `load': undefined method `join' for nil:NilClass (NoMethodError)
The workaround (also documented in issue #155) is to replace Dotenv::Railtie.load with:
Dotenv.load(File.expand_path("../../.env.#{Rails.env}", __FILE__))
Apparently this is only a problem when using rails 4.1.
Was also having this problem, but manage to get it to work by having this in my secrets.yml file:
production:
secret_key_base: ENV["SECRET_KEY_BASE"]
It worked after removing the <%= %>