Можете ли вы получить имя пользователя БД, pw, имя базы данных в Rails?

147

Я пишу грабли, которые выполняют работу некоторых БД вне Rails / ActiveRecord.

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

Я хотел бы получить его, чтобы я мог использовать его для подключения, как это ...

con = Mysql.real_connect("host", "user", "pw", "current_db")
Итан
источник

Ответы:

245

Из рельсов вы можете создать объект конфигурации и получить от него необходимую информацию:

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 :: Configuration.

Это просто использует YAML :: load для загрузки конфигурации из файла конфигурации базы данных ( database.yml), который вы можете использовать сами, чтобы получить информацию извне среды rails:

require 'YAML'
info = YAML::load(IO.read("database.yml"))
print info["production"]["host"]
print info["production"]["database"]
...
Роберт Гэмбл
источник
27
В более поздних Rails вам не нужно создавать конфигурацию, вы можете получить ее черезRails.configuration
Брайан Ларсен
для rails 3.0.0 требуется 'yaml' и YAML :: load (IO.read ("config / database.yml")) работает отлично!
Arivarasan 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̶ ̶̶ original̶ original̶ Я вижу ответ @KenB.
млт
156

Ответ Брайана в приведенном выше комментарии заслуживает чуть большего разоблачения:

>> Rails.configuration.database_configuration[Rails.env]
=> {"encoding"=>"unicode", "username"=>"postgres", "adapter"=>"postgresql", "port"=>5432, "host"=>"localhost", "password"=>"postgres", "database"=>"mydb", "pool"=>5}
KeNB
источник
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.

qqbenq
источник
10
Кажется, это единственное, что объясняет слияние database.ymlконфигурации с DATABASE_URLпеременной среды.
tpett
Я не могу говорить за кого-то еще, но это прекрасно. Я хотел перепроверить программно, что я указываю на правильную базу данных
jaydel
3

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

 ActiveRecord::Base.configurations[Rails.env]
derosm2
источник
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

ссылка: http://effectif.com/articles/database-yml-should-be-checked-in

edwardsharp
источник