Dreeub
Dreeub

Reputation: 396

Using the backup gem how can I get database authentications details from rails database.yml

I'm testing out the backup gem

http://backup.github.io/backup/v4/utilities/

I understand that I've to create a db_backup.rb with the configuration for example

Model.new(:my_backup, 'My Backup') do
  database MySQL do |db|
    # To dump all databases, set `db.name = :all` (or leave blank)
    db.name               = "my_database_name"
    db.username           = "my_username"
    db.password           = "my_password"
    db.host               = "localhost"
    db.port               = 3306

However I'm not able to find out how to get those details from the Rails database.yml. I've tried something like this:

  env = defined?(RAILS_ENV) ? RAILS_ENV : 'development'
  @settings = YAML.load(File.read(File.join( "config", "database.yml")))

But I guess there should be a better way.

Upvotes: 0

Views: 107

Answers (2)

max
max

Reputation: 102055

Use ActiveRecord's own configuration handling:

require 'active_record'
require 'yaml'

Model.new(:my_backup, 'My Backup') do
  database MySQL do |db|
    config = {
      # these are the default values
      host: 'localhost'
      port: 3306
    }.merge(load_configuration(ENV['RAILS_ENV'] || 'development'))
    config.each_pair do |key, value|
      db.public_send("#{key}=", value)
    end
  end

  # this loads the configuration from file and memoizes it
  def load_configuration(env)
    @file_config ||= YAML.load(File.read(File.join( "config", "database.yml")))  
    @configurations ||= ActiveRecord::ConnectionHandling::MergeAndResolveDefaultUrlConfig.new(file_config).resolve
    @configurations[env]
  end
end

The key advantage here is that it will merge the values from ENV['DATABASE_URL']. Which is very important since you should avoid adding database credentials to config/database.yml.

A good habit is to specify only the connection adapter and base essentials in database.yml. Use ENV['DATABASE_URL'] for usernames, passwords and everything else.

Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard.
- https://12factor.net/config

See:

Upvotes: 0

spickermann
spickermann

Reputation: 106932

I would do something like this:

env = defined?(RAILS_ENV) ? RAILS_ENV : 'development'
config = YAML.load_file(File.join('config', 'database.yml'))[env]

Model.new(:my_backup, 'My Backup') do
  database MySQL do |db|
    config.each_pair do |key, value|
      db.public_send("#{key}=", value)
    end
    # ...

Upvotes: 1

Related Questions