Você pode obter o nome de usuário do banco de dados, pw, nome do banco de dados no Rails?

146

Estou escrevendo uma tarefa de rake que faz algum trabalho de banco de dados fora do Rails / ActiveRecord.

Existe uma maneira de obter as informações de conexão do banco de dados (host, nome de usuário, senha, nome do banco de dados) para o ambiente atual, conforme definido em database.yml?

Gostaria de obtê-lo para que eu possa usá-lo para conectar assim ...

con = Mysql.real_connect("host", "user", "pw", "current_db")
Ethan
fonte

Respostas:

244

De dentro dos trilhos, você pode criar um objeto de configuração e obter as informações necessárias:

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"]

Veja a documentação para Rails :: Configuration para detalhes.

Isso apenas usa YAML :: load para carregar a configuração do arquivo de configuração do banco de dados ( database.yml), que você pode usar para obter as informações de fora do ambiente de rails:

require 'YAML'
info = YAML::load(IO.read("database.yml"))
print info["production"]["host"]
print info["production"]["database"]
...
Robert Gamble
fonte
27
No Rails mais recentes, você não precisa para criar a configuração, você pode obtê-lo viaRails.configuration
Bryan Larsen
para o Rails 3.0.0, é necessário 'yaml' e YAML :: load (IO.read ("config / database.yml")) funciona bem!
Arivarasan L
Se alguns deles tiverem valores nulos (no meu caso: host, nome de usuário e senha), quais são os padrões que o Rails usaria?
Dennis
3
Cuidado ao usar o YAML - as versões modernas do Rails também filtram o conteúdo do arquivo através do ERB primeiro.
Kelvin
@BryanLarsen C̶o̶u̶l̶d̶ ̶e̶l̶a̶b̶o ̶R̶a̶i̶l̶s̶.̶c̶o̶n̶f̶i̶g̶u̶r̶a̶t̶i̶o̶n̶edited original original original original original original original original original original original Eu vejo a resposta @KenB.
mlt
156

A resposta de Bryan no comentário acima merece um pouco mais de exposição:

>> Rails.configuration.database_configuration[Rails.env]
=> {"encoding"=>"unicode", "username"=>"postgres", "adapter"=>"postgresql", "port"=>5432, "host"=>"localhost", "password"=>"postgres", "database"=>"mydb", "pool"=>5}
KenB
fonte
7
Atualizando para o Rails 4.1 na Heroku, eu tive que mudar essa linha para: ActiveRecord :: Base.configurations [Rails.env]
quainjn
82
ActiveRecord::Base.connection_config

retorna a configuração da conexão em um hash:

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

Conforme tpettobservado em seu comentário: esta solução é responsável pela mesclagem da configuração de database.ymle para a variável de ambiente DATABASE_URL.

qqbenq
fonte
10
Esse parece ser o único responsável pela mesclagem da database.ymlconfiguração com a DATABASE_URLvariável de ambiente.
precisa saber é
Não posso falar por mais ninguém, mas isso é perfeito. Eu queria verifique programaticamente que eu estava apontando para o banco de dados correto
jaydel
3

Eu acho que essa é a solução mais simples. Após alguns testes (pelo menos no Rails 5.2), isso resolverá o DATABASE_URL corretamente.

 ActiveRecord::Base.configurations[Rails.env]
derosm2
fonte
1

Pergunta antiga, mas essa foi uma das minhas primeiras paradas para descobrir como fazer isso, e acho que isso pode ajudar outra pessoa. Normalmente, tenho arquivos .my.cnf no diretório inicial. Portanto, usar a gem 'parseconfig' e alguma sintaxe do ERB no meu arquivo de configuração database.yml significa que tenho um arquivo dinâmico que me permite sentir bem ao verificar o controle de origem e também simplificar as implantações (no meu caso). Observe também a lista de soquetes comuns, facilitando a movimentação do meu aplicativo para diferentes sistemas operacionais que podem ter um caminho de soquete Unix diferente.

<% 
    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
fonte