¿Puedes obtener el nombre de usuario DB, pw, el nombre de la base de datos en Rails?

147

Estoy escribiendo una tarea de rastrillo que hace algún trabajo de base de datos fuera de Rails / ActiveRecord.

¿Hay alguna manera de obtener la información de conexión de la base de datos (host, nombre de usuario, contraseña, nombre de la base de datos) para el entorno actual como se define en database.yml?

Me gustaría obtenerlo para poder usarlo para conectarme así ...

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

Respuestas:

245

Desde dentro de los rieles puede crear un objeto de configuración y obtener la información necesaria de él:

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

Consulte la documentación de Rails :: Configuration para más detalles.

Esto solo usa YAML :: load para cargar la configuración desde el archivo de configuración de la base de datos ( database.yml) que puede usar usted mismo para obtener la información desde fuera del entorno de rails:

require 'YAML'
info = YAML::load(IO.read("database.yml"))
print info["production"]["host"]
print info["production"]["database"]
...
Robert Gamble
fuente
27
En Rails más recientes, no necesita crear la configuración, puede obtenerla a través deRails.configuration
Bryan Larsen
para rails 3.0.0, requiere 'yaml' y YAML :: load (IO.read ("config / database.yml")) ¡funciona bien!
Arivarasan L
Si algunos de ellos tienen valores nulos (en mi caso: host, nombre de usuario y contraseña), ¿cuáles son los valores predeterminados que usaría Rails?
Dennis
3
Tenga cuidado al usar YAML: las versiones modernas de Rails también filtrarán primero el contenido del archivo a través de ERB.
Kelvin
@BryanLarsen Podría elaborar? ̶ ̶ ̶R̶a̶i̶l̶s̶.̶c̶o̶n̶f̶i̶g̶u̶r̶a̶t̶i̶o̶n̶̶ entonces qué ser diferente de la respuesta? ̶ Tal vez la respuesta fue corregida de originales. Veo @KenB respuesta.
mlt
156

La respuesta de Bryan en el comentario anterior merece un poco más de exposición:

>> Rails.configuration.database_configuration[Rails.env]
=> {"encoding"=>"unicode", "username"=>"postgres", "adapter"=>"postgresql", "port"=>5432, "host"=>"localhost", "password"=>"postgres", "database"=>"mydb", "pool"=>5}
KenB
fuente
77
Al actualizar a Rails 4.1 en Heroku, tuve que cambiar esta línea a: ActiveRecord :: Base.configurations [Rails.env]
quainjn
82
ActiveRecord::Base.connection_config

devuelve la configuración de conexión en un hash:

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

Como se tpettcomentó en su comentario: esta solución representa la fusión de la configuración desde database.ymly desde la variable de entorno DATABASE_URL.

qqbenq
fuente
10
Este parece ser el único que explica la fusión de la database.ymlconfiguración con la DATABASE_URLvariable de entorno.
tpett
No puedo hablar por nadie más, pero esto es perfecto. Quería verificar mediante programación que estaba apuntando a la base de datos correcta
jaydel
3

Creo que esta es la solución más simple. Después de algunas pruebas (en Rails 5.2 al menos), esto resolverá DATABASE_URL correctamente.

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

Antigua pregunta, pero esta fue una de mis primeras paradas para buscar cómo hacer esto, así que creo que esto puede ayudar a alguien más. Normalmente tengo archivos .my.cnf en el directorio de inicio. Entonces, usar la gema 'parseconfig' y alguna sintaxis de ERB en mi archivo de configuración database.yml significa que tengo un archivo dinámico que puedo sentir bien al registrar el control de origen y también simplificar las implementaciones (en mi caso). También tenga en cuenta la lista de sockets comunes, esto hace que sea más fácil mover mi aplicación a diferentes sistemas operativos que pueden tener una ruta de socket 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
fuente