Чи можете ви отримати ім'я користувача DB, pw, ім'я бази даних в Rails?


146

Я пишу завдання граблі, яке виконує деякі БД поза межами Rails / ActiveRecord.

Чи є спосіб отримати інформацію про з'єднання БД (хост, ім'я користувача, пароль, ім'я БД) для поточного середовища, як визначено в database.yml?

Я хотів би отримати його, щоб я міг використовувати його для з'єднання, як це ...

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

Відповіді:


244

Зсередини рейок можна створити об’єкт конфігурації та отримати необхідну інформацію від нього:

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

Докладніше див. Документацію для Rails :: Конфігурація.

Це просто використовує YAML :: load для завантаження конфігурації з файлу конфігурації бази даних ( database.yml), який ви можете використовувати самостійно, щоб отримати інформацію з зовнішнього середовища рейки:

require 'YAML'
info = YAML::load(IO.read("database.yml"))
print info["production"]["host"]
print info["production"]["database"]
...

27
В останніх Rails вам не потрібно створювати конфігурацію, ви можете отримати її черезRails.configuration
Брайан Ларсен,

для рейок 3.0.0 вимагають 'yaml' і YAML :: load (IO.read ("config / database.yml")) працює нормально!
Аріварасан L

Якщо деякі з них мають нульові значення (у моєму випадку: хост, ім’я користувача та пароль), які параметри за замовчуванням використовуються Rails?
Денніс

3
Обережно з використанням YAML - сучасні версії Rails також спочатку фільтрують вміст файлу через ERB.
Кельвін

@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̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶̶ ed̶̶ ed̶̶̶̶̶̶ ed̶ Я бачу відповідь @KenB.
mlt

156

Відповідь Брайана в коментарі вище заслуговує на трохи більше викриття:

>> Rails.configuration.database_configuration[Rails.env]
=> {"encoding"=>"unicode", "username"=>"postgres", "adapter"=>"postgresql", "port"=>5432, "host"=>"localhost", "password"=>"postgres", "database"=>"mydb", "pool"=>5}

7
Оновлення до Rails 4.1 на Heroku, мені довелося переключити цю лінію на: ActiveRecord :: Base.configurations [Rails.env]
quainjn

82
ActiveRecord::Base.connection_config

повертає конфігурацію з'єднання в хеші:

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

Як tpettзазначається у коментарі: це рішення пояснює об'єднання конфігурації із database.ymlзмінної середовища та з неї DATABASE_URL.


10
Це здається єдиним, що пояснює об'єднання database.ymlконфігурації зі DATABASE_URLзмінною середовища.
tpett

Я не можу говорити ні за кого іншого, але це ідеально. Я хотів програмно перевірити, чи я вказував на правильну базу даних
jaydel

3

Я думаю, що це найпростіше рішення. Після деякого тестування (принаймні в Rails 5.2) це дозволить правильно вирішити DATABASE_URL.

 ActiveRecord::Base.configurations[Rails.env]

1

Старе питання, але це була одна з моїх перших зупинок у пошуку, як це зробити, тому я думаю, що це може допомогти комусь іншому. Я зазвичай маю .my.cnf файли в домашньому каталозі. Отже, використовуючи дорогоцінний камінь parseconfig та деякі синтаксиси ERB в моєму конфігураційному файлі database.yml, це означає, що у мене є динамічний файл, який я можу почувати себе добре під час перевірки джерела управління, а також спростити розгортання (у моєму випадку). Також зверніть увагу на перелік поширених сокетів, це полегшує переміщення мого додатка до різних операційних систем, які можуть мати інший шлях до розетки Unix.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.