Bạn có thể lấy tên người dùng DB, pw, tên cơ sở dữ liệu trong Rails không?


146

Tôi đang viết một tác vụ cào mà một số DB hoạt động bên ngoài Rails / ActiveRecord.

Có cách nào để lấy thông tin kết nối DB (máy chủ, tên người dùng, mật khẩu, tên DB) cho môi trường hiện tại như được định nghĩa trong database.ymlkhông?

Tôi muốn có được nó để tôi có thể sử dụng nó để kết nối như thế này ...

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

Câu trả lời:


244

Từ trong đường ray, bạn có thể tạo một đối tượng cấu hình và có được thông tin cần thiết từ nó:

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

Xem tài liệu cho Rails :: Cấu hình để biết chi tiết.

Điều này chỉ sử dụng YAML :: load để tải cấu hình từ tệp cấu hình cơ sở dữ liệu ( database.yml) mà bạn có thể tự sử dụng để lấy thông tin từ bên ngoài môi trường đường ray:

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

27
Trong Rails gần đây, bạn không cần tạo cấu hình, bạn có thể lấy nó quaRails.configuration
Bryan Larsen

đối với đường ray 3.0.0, yêu cầu 'yaml' và YAML :: load (IO.read ("config / database.yml")) hoạt động tốt!
Arivaraan L

Nếu một số trong số đó có giá trị không (trong trường hợp của tôi: máy chủ, tên người dùng và mật khẩu), các mặc định mà Rails sẽ sử dụng là gì?
Dennis

3
Cẩn thận về việc sử dụng YAML - phiên bản hiện đại của Rails cũng sẽ lọc nội dung tệp qua ERB trước tiên.
Kelvin

@BryanLarsen có thể giúp bạn xây dựng? ̶ ̶ ̶R̶a̶i̶l̶s̶.̶c̶o̶n̶f̶i̶g̶u̶r̶a̶t̶i̶o̶n̶̶ sau đó điều gì là khác nhau từ câu trả lời? ̶ Có lẽ câu trả lời đã được chỉnh sửa từ gốc. Tôi thấy @KenB trả lời.
mlt

156

Câu trả lời của Bryan trong bình luận ở trên xứng đáng được tiếp xúc nhiều hơn một chút:

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

7
Nâng cấp lên Rails 4.1 trên Heroku, tôi đã phải chuyển dòng này thành: ActiveRecord :: Base.configurations [Rails.env]
quainjn

82
ActiveRecord::Base.connection_config

trả về cấu hình kết nối trong hàm băm:

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

Như đã tpettnhận xét trong nhận xét của họ: giải pháp này chiếm sự hợp nhất cấu hình từ database.ymlvà từ biến môi trường DATABASE_URL.


10
Đây dường như là người duy nhất tính đến việc hợp nhất database.ymlcấu hình với DATABASE_URLbiến môi trường.
tpett

Tôi không thể nói cho ai khác, nhưng điều này là hoàn hảo. Tôi muốn kiểm tra lại theo chương trình rằng tôi đã chỉ vào đúng cơ sở dữ liệu
jaydel

3

Tôi nghĩ rằng đây là giải pháp đơn giản nhất. Sau một số thử nghiệm (trong Rails 5.2 ít nhất), điều này sẽ giải quyết chính xác DATABASE_URL.

 ActiveRecord::Base.configurations[Rails.env]

1

Câu hỏi cũ nhưng đây là một trong những điểm dừng đầu tiên của tôi khi tìm cách làm điều này để tôi nghĩ rằng điều này có thể giúp đỡ người khác. Tôi thường có các tập tin .my.cnf trong thư mục nhà. Vì vậy, sử dụng đá quý 'Parseconfig' và một số cú pháp ERB trong tệp cấu hình cơ sở dữ liệu của tôi có nghĩa là tôi đã có tệp động mà tôi có thể cảm thấy tốt khi kiểm tra kiểm soát nguồn và cũng đơn giản hóa việc triển khai (trong trường hợp của tôi). Cũng lưu ý danh sách các ổ cắm phổ biến, điều này giúp việc di chuyển ứng dụng của tôi sang các hệ điều hành khác nhau có thể có đường dẫn ổ cắm Unix khác nhau dễ dàng hơn.

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.