166

I'm writing a rake task that does some DB work outside of Rails/ActiveRecord.

Is there a way to get the DB connection info (host, username, password, DB name) for the current environment as defined in database.yml?

I'd like to get it so I can use it to connect like this...

con = Mysql.real_connect("host", "user", "pw", "current_db")
Ethan
  • 57,819
  • 63
  • 187
  • 237

8 Answers8

263

From within rails you can create a configuration object and obtain the necessary information from it:

config   = Rails.configuration.database_configuration
host     = config[Rails.env]["host"]
database = config[Rails.env]["database"]
username = config[Rails.env]["username"]
password = config[Rails.env]["password"]

See the documentation for Rails::Configuration for details.

This just uses YAML::load to load the configuration from the database configuration file (database.yml) which you can use yourself to get the information from outside the rails environment:

require 'YAML'
info = YAML::load(IO.read("database.yml"))
print info["production"]["host"]
print info["production"]["database"]
...
Sam Hartman
  • 6,210
  • 3
  • 23
  • 40
Robert Gamble
  • 106,424
  • 25
  • 145
  • 137
  • 28
    In more recent Rails, you don't need to create the configuration, you can get it via `Rails.configuration` – Bryan Larsen Aug 18 '10 at 17:37
  • for rails 3.0.0, require 'yaml' and YAML::load(IO.read("config/database.yml")) works fine! – Arivarasan L Jan 02 '14 at 14:26
  • If some of those have nil values (in my case: host, username, and password), what are the defaults that Rails would use? – Dennis May 26 '14 at 18:48
  • 4
    Careful about using YAML - modern versions of Rails will also filter the file contents through ERB first. – Kelvin Dec 24 '14 at 19:31
  • @BryanLarsen C̶o̶u̶l̶d̶ ̶y̶o̶u̶ ̶e̶l̶a̶b̶o̶r̶a̶t̶e̶?̶ ̶`̶R̶a̶i̶l̶s̶.̶c̶o̶n̶f̶i̶g̶u̶r̶a̶t̶i̶o̶n̶`̶ ̶t̶h̶e̶n̶ ̶w̶h̶a̶t̶ ̶t̶o̶ ̶b̶e̶ ̶d̶i̶f̶f̶e̶r̶e̶n̶t̶ ̶f̶r̶o̶m̶ ̶t̶h̶e̶ ̶a̶n̶s̶w̶e̶r̶?̶ Perhaps the answer was edited from original. I see @KenB answer. – mlt Nov 02 '16 at 02:10
  • This does not take `ENV["DATABASE_URL"]` into account which will override the settings from the YAML file. – max Jan 23 '19 at 23:30
162

Bryan's answer in the comment above deserves a little more exposure:

>> Rails.configuration.database_configuration[Rails.env]
=> {"encoding"=>"unicode", "username"=>"postgres", "adapter"=>"postgresql", "port"=>5432, "host"=>"localhost", "password"=>"postgres", "database"=>"mydb", "pool"=>5}
KenB
  • 6,587
  • 2
  • 35
  • 31
  • 8
    Upgrading to Rails 4.1 on Heroku, I had to switch this line to: ActiveRecord::Base.configurations[Rails.env] – quainjn Jun 04 '14 at 18:49
96
ActiveRecord::Base.connection_config

returns the connection configuration in a hash:

=> {:adapter=>ADAPTER_NAME, :host=>HOST, :port=>PORT, 
    :database=>DB, :pool=>POOL, :username=>USERNAME, 
    :password=>PASSWORD} 

As tpett remarked in their comment: this solution accounts for merging the configuration from database.yml and from the environment variable DATABASE_URL.

qqbenq
  • 10,220
  • 4
  • 40
  • 45
  • 10
    This seems to be the only one that accounts for the merging of `database.yml` configuration with the `DATABASE_URL` environment variable. – tpett Aug 01 '16 at 22:18
  • I can't speak for anyone else, but this is perfect. I wanted to double check programmatically that I was pointing at the correct database – jaydel Apr 11 '19 at 14:27
7

As of Rails 6.1, ActiveRecord::Base.connection_config is deprecated. The newer accessor is ActiveRecord::Base.connection_db_config

[1] pry(main)> ActiveRecord::Base.connection_db_config
=> #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fe04ae72e58
 @configuration_hash=
  {:adapter=>"postgresql",
   :encoding=>"utf8",
   :min_messages=>"WARNING",
   :host=>"localhost",
   :username=>"postgres",
   :password=>"P@ssw0rd",
   :port=>5432,
   :database=>"myapp_development"},
 @env_name="development",
 @name="primary">
danielricecodes
  • 3,446
  • 21
  • 23
Alex Dunae
  • 1,290
  • 3
  • 17
  • 28
6

I think this is the simplest solution. After some testing (in Rails 5.2 at least) this will resolve DATABASE_URL correctly.

 ActiveRecord::Base.configurations[Rails.env]
derosm2
  • 138
  • 1
  • 5
4

In Rails 6.1+, you can use:

ActiveRecord::Base.connection_db_config.configuration_hash

This returns a hash containing the current environment's connection information:

{
  :adapter=>"postgresql",
  :encoding=>"utf8",
  :min_messages=>"WARNING",
  :host=>"localhost",
  :username=>"postgres",
  :password=>"P@ssw0rd",
  :port=>5432,
  :database=>"my_app_development"
}
danielricecodes
  • 3,446
  • 21
  • 23
1

Old question but this was one of my first stops in looking up how to do this so I figure this may help someone else. I normally have .my.cnf files in the home directory. So using the 'parseconfig' gem and some ERB syntax in my database.yml config file means I've got dynamic file that I can feel good about checking into source control and also simplify deployments (in my case). Also note the list of common sockets, this makes it easier to move my app to different operating systems that might have a different Unix socket path.

<% 
    require 'parseconfig'
    c=ParseConfig.new('../../.my.cnf') %>

mysqlevn: &mysql
  adapter: mysql 
  username: <%= c.params['client']['user'] %>
  password: <%= c.params['client']['password'] %>
  host: localhost 
  socket: <%= [ 
  '/var/run/mysqld/mysqld.sock',
  '/var/lib/mysql/mysql.sock',
  '/tmp/mysqld.sock',
  '/tmp/mysql.sock'].detect { |socket| File.exist?(socket) } %>

production:
  database: app_production
  <<: *mysql


development:
  database: app_development 
  <<: *mysql

# Do not set this db to the same as development or production.
test:
  database: app_test
  <<: *mysql

ref: http://effectif.com/articles/database-yml-should-be-checked-in

edwardsharp
  • 1,232
  • 10
  • 17
0

I was trying to get the username and password in order to connect to pgAdmin. I tried every method above and couldn't find the values for username and password for my database in development in rails 7.

It turns out pgAdmin didn't actually need the username and password for the individual app's database; instead, it will authenticate to the postgres server and hence have access to all databases on the server.

This may solve the problem for people needing the username and password for similar reasons to me.


But this doesn't explain why I was unable to get the username and password for my specific (rails 7) app. The best I can guess is it's because Rails 7 defaults to using default credentials to connect to the local database.

In my case (PostgreSQL) uses the username "postgres" by default with no password or a blank password.

So if you check in config/database.yml and the dev environment is referring to default, and those defaults don't list anything for username and password explicitly, it might be using your database's default creds. I couldn't find any way to confirm this though, it's merely my suspicion based on what I see in rails 7's database.yml, the fact ENV gives nothing related to the db, and that all the above methods gave no results.

stevec
  • 41,291
  • 27
  • 223
  • 311