Benjamin Sunderland
Benjamin Sunderland

Reputation: 1

Dotenv variable not loading

I am trying to access my DOTENV variable in my API request but it is returning nothing.

I have added it to my gem file.

I have added MOVIE_API = <secret-key> to a file .dotenv in my root. Below is the code where I require it and try to access it but it is returning empty.

// Application.rb
 
 Dotenv::Railtie.load 

// models/movie_api.rb

require 'httparty'
require 'dotenv'

class MovieDB
  include HTTParty

  attr_reader :base_uri

  def initialize
    @base_uri = 'http://api.themoviedb.org/3/movie/'
  end

  def top_rated
    HTTParty.get("#{@base_uri}popular?api_key=#{ENV["MOVIE_DB"]}")
  end
end

puts ENV["MOVIE_DB"] // returning empty


.

Upvotes: 0

Views: 61

Answers (1)

max
max

Reputation: 101811

If you really want to use DotEnv in a Rails project you just add gem 'dotenv-rails' to your gemfile and run bundle install.

Rails will automatically require the gems in your gemfile in application.rb and load your dotenv configuration files provided they are appropriately named. It helps if you actually use the same name for your keys and validate the configuration.

Calling them "dotenv variables" is a bit silly. The whole idea behind Dotenv is that it provided a more convenient and portable way to pass configuration to the application than setting ENV vars through the shell or when starting the process. From the perspective of the application they are indistinguishable to other ENV vars.

YAGNI

Rails 5.1 (released back in 2017) introduced encrypted secrets which both provides a standardized way to manage credentials and avoids many of the security pitfalls of putting API keys and other sensitive data in a plaintext text file.

I would do something more like this:

# app/clients/movie_db.rb
class MovieDB
  include HTTParty
  base_uri 'http://api.themoviedb.org/3/movie/'

  # This is an example of constructor injection 
  def initialize(api_key: api_key_from_credentials)
    @default_options = {
      api_key: api_key
    }
  end

  def top_rated(**kwargs)
    # Call the HTTP methods on the class instead to use HTTParty as 
    # a mixin
    self.class.get('/popular', @default_options.merge(kwargs))
  end

  private

  def api_key_from_credentials
    Rails.application.credentials.movie_db.fetch(:api_key)
  end
end

Upvotes: 0

Related Questions