Pouvez-vous obtenir le nom d'utilisateur DB, pw, le nom de la base de données dans Rails?

147

J'écris une tâche de râteau qui effectue un travail de base de données en dehors de Rails / ActiveRecord.

Existe-t-il un moyen d'obtenir les informations de connexion à la base de données (hôte, nom d'utilisateur, mot de passe, nom de base de données) pour l'environnement actuel tel que défini dans database.yml?

J'aimerais l'obtenir pour pouvoir l'utiliser pour me connecter comme ça ...

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

Réponses:

245

À partir des rails, vous pouvez créer un objet de configuration et en obtenir les informations nécessaires:

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

Consultez la documentation de Rails :: Configuration pour plus de détails.

Cela utilise simplement YAML :: load pour charger la configuration à partir du fichier de configuration de la base de données ( database.yml) que vous pouvez utiliser vous-même pour obtenir les informations de l'extérieur de l'environnement rails:

require 'YAML'
info = YAML::load(IO.read("database.yml"))
print info["production"]["host"]
print info["production"]["database"]
...
Robert Gamble
la source
27
Dans les Rails plus récents, vous n'avez pas besoin de créer la configuration, vous pouvez l'obtenir viaRails.configuration
Bryan Larsen
pour les rails 3.0.0, require 'yaml' et YAML :: load (IO.read ("config / database.yml")) fonctionne très bien!
Arivarasan L
Si certains d'entre eux ont des valeurs nulles (dans mon cas: hôte, nom d'utilisateur et mot de passe), quelles sont les valeurs par défaut que Rails utiliserait?
Dennis
3
Attention à l'utilisation de YAML - les versions modernes de Rails filtreront également le contenu du fichier via ERB en premier.
Kelvin
@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̶ ̶n̶e̶ ̶difefefer. Je vois la réponse de @KenB.
mlt
156

La réponse de Bryan dans le commentaire ci-dessus mérite un peu plus de visibilité:

>> Rails.configuration.database_configuration[Rails.env]
=> {"encoding"=>"unicode", "username"=>"postgres", "adapter"=>"postgresql", "port"=>5432, "host"=>"localhost", "password"=>"postgres", "database"=>"mydb", "pool"=>5}
KenB
la source
7
Mise à niveau vers Rails 4.1 sur Heroku, j'ai dû changer cette ligne en: ActiveRecord :: Base.configurations [Rails.env]
quainjn
82
ActiveRecord::Base.connection_config

renvoie la configuration de la connexion dans un hachage:

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

Comme tpettremarqué dans leur commentaire: cette solution prend en compte la fusion de la configuration depuis database.ymlet depuis la variable d'environnement DATABASE_URL.

qqbenq
la source
10
Cela semble être le seul qui explique la fusion de la database.ymlconfiguration avec la DATABASE_URLvariable d'environnement.
tpett
Je ne peux parler pour personne d'autre, mais c'est parfait. Je voulais vérifier par programme que je
pointais
3

Je pense que c'est la solution la plus simple. Après quelques tests (dans Rails 5.2 au moins), cela résoudra DATABASE_URL correctement.

 ActiveRecord::Base.configurations[Rails.env]
derosm2
la source
1

Ancienne question, mais c'était l'un de mes premiers arrêts pour chercher comment faire cela, alors je suppose que cela peut aider quelqu'un d'autre. J'ai normalement des fichiers .my.cnf dans le répertoire personnel. Donc, en utilisant le gem 'parseconfig' et une certaine syntaxe ERB dans mon fichier de configuration database.yml signifie que j'ai un fichier dynamique que je peux me sentir bien pour vérifier dans le contrôle de code source et également simplifier les déploiements (dans mon cas). Notez également la liste des sockets communs, cela facilite le déplacement de mon application vers différents systèmes d'exploitation pouvant avoir un chemin de socket Unix différent.

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

réf: http://effectif.com/articles/database-yml-should-be-checked-in

Edwardsharp
la source