Jingqiang Zhang
Jingqiang Zhang

Reputation: 1049

How to get global variables from database config file in rails application?

I want to get secret informations from other place beside rails application and the host. I made a global variable file under config/initializers to get the keys. Then set them in the database connection file. Like this:

config/initializers/get_secrets.rb

@@username = 'A'
@@password = 'B'

config/database.yml

development:
  adapter: mysql2
  encoding: utf8
  database: my_db_name
  username: <%= @@username %>
  password: <%= @@password %>
  host: 127.0.0.1
  port: 3306

When ran rails console, got:

./config/initializers/get_secrets.rb:1: warning: class variable access from toplevel
(erb):10: warning: class variable access from toplevel
> 

It seems not a good usage in this case. Then is there a right way?

Upvotes: 0

Views: 530

Answers (1)

Veridian Dynamics
Veridian Dynamics

Reputation: 1406

In Rails 5.2+, we have a master.key file and a credentials YAML file. The master.key file encrypts your credentials (so never show anyone this key except your server).

You can activate this by doing:

EDITOR=vim rails credentials:edit

The file:

aws:
    key: 123
google_key: 456
secret_key_base: f230ffddd1d1f151j3bchjas9a292j221...

If you want to use a credential, it looks like this:

Rails.application.credentials.google_key

or for nested resources like the AWS one:

Rails.application.credentials.aws[:key]

But if you're on Rails 5.1 or less, you don't have this ability. So, you do it in a different way:

  1. Environment variables. Your program environment can always export an ENV and retrieve it. I always do this for simple nuisances like test email passwords:

    export GMAIL_PASSWORD="1234" and its usage, ENV['GMAIL_PASSWORD']

  2. Secrets.yml. This is a file that basically predates master.key + credentials by functioning as an in between credential handler for your environments. It's janky and often erroneously committed to repos by accident, but we do what we can:

    development:
      secret_key_base: 1112sdasae1d13d1tfd1d3... 
    
    
      GMAIL_PASSWORD: '1234'
    
    test:
      secret_key_base: _your_secret_ as above
    
    production:
      secret_key_base: <%= secure_token %>
    

And it is accessed like Rails.application.secrets.GMAIL_PASSWORD

If you cannot access your variables, it may be because the secrets.yml file is not being loading in or you are in the wrong environment. Notice those vars are nested in particular environments.

Upvotes: 1

Related Questions