Bisakah Anda mendapatkan DB username, pw, nama database di Rails?

147

Saya sedang menulis tugas menyapu yang melakukan beberapa pekerjaan DB di luar Rails / ActiveRecord.

Apakah ada cara untuk mendapatkan info koneksi DB (host, nama pengguna, kata sandi, nama DB) untuk lingkungan saat ini sebagaimana didefinisikan dalam database.yml?

Saya ingin mendapatkannya sehingga saya dapat menggunakannya untuk terhubung seperti ini ...

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

Jawaban:

245

Dari dalam rel Anda dapat membuat objek konfigurasi dan mendapatkan informasi yang diperlukan dari itu:

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

Lihat dokumentasi untuk Rails :: Configuration untuk detailnya.

Ini hanya menggunakan YAML :: load untuk memuat konfigurasi dari file konfigurasi database ( database.yml) yang dapat Anda gunakan sendiri untuk mendapatkan informasi dari luar lingkungan rails:

require 'YAML'
info = YAML::load(IO.read("database.yml"))
print info["production"]["host"]
print info["production"]["database"]
...
Robert Gamble
sumber
27
Di Rails yang lebih baru, Anda tidak perlu membuat konfigurasi, Anda bisa mendapatkannya melaluiRails.configuration
Bryan Larsen
untuk rail 3.0.0, memerlukan 'yaml' dan YAML :: load (IO.read ("config / database.yml")) berfungsi dengan baik!
Arivarasan L
Jika beberapa dari mereka memiliki nilai nihil (dalam kasus saya: host, nama pengguna, dan kata sandi), apa standar yang akan digunakan Rails?
Dennis
3
Hati-hati menggunakan YAML - Rails versi modern juga akan memfilter konten file melalui ERB terlebih dahulu.
Kelvin
@Br @r @dddddddddddddddjdjdjdjdjdjdjdjfdjfjfjfjfjfjfjfjfjrggtgtgtg ttg ̶R̶a̶i̶l̶s̶.̶c̶o̶n̶f̶i̶g̶u̶r̶a̶t̶i̶o̶n̶ttg tg tt tt tg tt tg tt tg tg ttg tg ttg ttg ttg ttg. Saya melihat jawaban @KenB.
mlt
156

Jawaban Bryan dalam komentar di atas patut mendapat sedikit paparan:

>> Rails.configuration.database_configuration[Rails.env]
=> {"encoding"=>"unicode", "username"=>"postgres", "adapter"=>"postgresql", "port"=>5432, "host"=>"localhost", "password"=>"postgres", "database"=>"mydb", "pool"=>5}
KenB
sumber
7
Memutakhirkan ke Rails 4.1 di Heroku, saya harus mengganti baris ini ke: ActiveRecord :: Base.configurations [Rails.env]
quainjn
82
ActiveRecord::Base.connection_config

mengembalikan konfigurasi koneksi dalam hash:

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

Seperti yang tpettdisebutkan dalam komentar mereka: solusi ini bertanggung jawab untuk menggabungkan konfigurasi dari database.ymldan dari variabel lingkungan DATABASE_URL.

qqbenq
sumber
10
Ini tampaknya menjadi satu-satunya yang memperhitungkan penggabungan database.ymlkonfigurasi dengan DATABASE_URLvariabel lingkungan.
tpett
Saya tidak bisa berbicara untuk orang lain, tetapi ini sempurna. Saya ingin mengecek secara terprogram bahwa saya menunjuk ke database yang benar
jaydel
3

Saya pikir ini adalah solusi paling sederhana. Setelah beberapa pengujian (setidaknya dalam Rails 5.2) ini akan menyelesaikan DATABASE_URL dengan benar.

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

Pertanyaan lama tapi ini adalah salah satu perhentian pertama saya dalam mencari cara melakukan ini, jadi saya pikir ini dapat membantu orang lain. Saya biasanya memiliki file .my.cnf di direktori home. Jadi menggunakan permata 'parseconfig' dan beberapa sintaks ERB di file config database.yml saya berarti saya punya file dinamis yang bisa saya rasakan baik dengan memeriksa ke dalam kontrol sumber dan juga menyederhanakan penyebaran (dalam kasus saya). Perhatikan juga daftar soket umum, ini membuatnya lebih mudah untuk memindahkan aplikasi saya ke sistem operasi yang berbeda yang mungkin memiliki jalur soket Unix yang berbeda.

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