Cách tốt nhất để tạo tùy chọn cấu hình tùy chỉnh cho ứng dụng Rails của tôi?


133

Tôi cần tạo một tùy chọn cấu hình cho ứng dụng Rails của mình. Nó có thể giống nhau cho tất cả các môi trường. Tôi thấy rằng nếu tôi đặt nó vào environment.rb, nó có sẵn trong chế độ xem của tôi, đó chính xác là những gì tôi muốn ...

environment.rb

AUDIOCAST_URI_FORMAT = http://blablalba/blabbitybla/yadda

Công trình tuyệt vời.

Tuy nhiên, tôi hơi khó chịu. Đây có phải là một cách tốt để làm điều đó? Có cách nào hông hơn không?

Câu trả lời:


191

Đối với cấu hình ứng dụng chung không cần lưu trữ trong bảng cơ sở dữ liệu, tôi muốn tạo một config.ymltệp trong thư mục cấu hình . Ví dụ của bạn, nó có thể trông như thế này:

defaults: &defaults
  audiocast_uri_format: http://blablalba/blabbitybla/yadda

development:
  <<: *defaults

test:
  <<: *defaults

production:
  <<: *defaults

Tệp cấu hình này được tải từ trình khởi tạo tùy chỉnh trong cấu hình / bộ khởi tạo :

# Rails 2
APP_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/config.yml")[RAILS_ENV]

# Rails 3+
APP_CONFIG = YAML.load_file(Rails.root.join('config/config.yml'))[Rails.env]

Nếu bạn đang sử dụng Rails 3, đảm bảo bạn không vô tình thêm dấu gạch chéo hàng đầu vào đường dẫn cấu hình tương đối của mình.

Sau đó, bạn có thể truy xuất giá trị bằng cách sử dụng:

uri_format = APP_CONFIG['audiocast_uri_format']

Xem Railscast này để biết chi tiết đầy đủ.


1
Bạn có thể cần YAML::ENGINE.yamler = 'syck'điều này để hoạt động stackoverflow.com/a/6140900/414220
evanrmurphy

45
Chỉ là một FYI, trong Rails 3.x bạn cần thay thế RAILS_ENVbằng Rails.envRAILS_ROOTbằng Rails.root.
JeanMertz

5
Đối với Rails 3+, bạn nên tham gia đường dẫn tương đối, không tuyệt đối. Không tiền tố cấu hình thư mục với dấu gạch chéo.
WST

10
Không chắc chắn về các phiên bản trước nhưng trong Rails 4.1 bạn có thể làmRails.application.config.whatever_you_want = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env]
d4rky

2
@ iphone007 thực sự có thể tải các tệp yaml tùy ý từ thư mục cấu hình. xem câu trả lời của smath dưới đây mà theo tôi bây giờ sẽ là câu trả lời được chấp nhận.
omnikron

82

Phiên bản Rails 3 của mã khởi tạo như sau (RAILS_ROOT & RAILS_ENV không được dùng nữa)

APP_CONFIG = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env]

Ngoài ra, Ruby 1.9.3 sử dụng Tâm lý làm cho các trường hợp hợp nhất trở nên nhạy cảm, do đó bạn sẽ cần thay đổi tệp cấu hình của mình để tính đến điều đó, ví dụ:

defaults: &DEFAULTS
  audiocast_uri_format: http://blablalba/blabbitybla/yadda

development:
  <<: *DEFAULTS

test:
  <<: *DEFAULTS

production:
  <<: *DEFAULTS

3
Bạn không cần "#{Rails.root.to_s}"; "#{Rails.root}"làm.
David J.

3
Tôi đề nghị Rails.root.join('config', 'config.yml')thay vì"#{Rails.root.to_s}/config/config.yml"
David J.

2
Và, thay vì APP_CONFIG, tôi khuyên bạn nên sử dụng:AppName::Application.config.custom
David J.

1
David, hai bình luận đầu tiên của bạn là cách thực hành tốt nhất và tôi sẽ tăng cường mã nhưng lần cuối tôi sẽ bỏ qua vì điều này có nghĩa là bạn cần nhớ thay đổi AppName mỗi khi bạn sử dụng mã này.
David Burrows

53

Đường ray> = 4.2

Chỉ cần tạo một YAMLtập tin vào config/thư mục, ví dụ : config/neo4j.yml.

Nội dung neo4j.ymlcó thể là một cái gì đó như dưới đây (Để đơn giản, tôi đã sử dụng mặc định cho tất cả các môi trường):

default: &default
  host: localhost
  port: 7474
  username: neo4j
  password: root

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default

trong config/application.rb:

module MyApp
  class Application < Rails::Application
    config.neo4j = config_for(:neo4j)
  end
end

Bây giờ, cấu hình tùy chỉnh của bạn có thể truy cập như dưới đây:

Rails.configuration.neo4j['host'] #=>localhost
Rails.configuration.neo4j['port'] #=>7474

Thêm thông tin

Tài liệu API chính thức của Rails mô tả config_forphương pháp như:

Thuận tiện cho việc tải config / foo.yml cho env Rails hiện tại.


Nếu bạn không muốn sử dụng một yamltập tin

Như hướng dẫn chính thức của Rails nói:

Bạn có thể định cấu hình mã của riêng mình thông qua đối tượng cấu hình Rails với cấu hình tùy chỉnh trong thuộc config.xtính.

Thí dụ

config.x.payment_processing.schedule = :daily
config.x.payment_processing.retries  = 3
config.x.super_debugger = true

Các điểm cấu hình này sau đó có sẵn thông qua đối tượng cấu hình:

Rails.configuration.x.payment_processing.schedule # => :daily
Rails.configuration.x.payment_processing.retries  # => 3
Rails.configuration.x.super_debugger              # => true
Rails.configuration.x.super_debugger.not_set      # => nil

Tài liệu tham khảo chính thức cho config_forphương pháp | Hướng dẫn đường ray chính thức


25

Bước 1: Tạo cấu hình / khởi tạo / appconfig.rb

require 'ostruct'
require 'yaml'

all_config = YAML.load_file("#{Rails.root}/config/config.yml") || {}
env_config = all_config[Rails.env] || {}
AppConfig = OpenStruct.new(env_config)

Bước 2: Tạo config / config.yml

common: &common
  facebook:
    key: 'asdjhasxas'
    secret : 'xyz'
  twitter:
    key: 'asdjhasxas'
    secret : 'abx'

development:
  <<: *common

test:
  <<: *common

production:
  <<: *common

Bước 3: Nhận hằng số bất cứ nơi nào trong mã

facebook_key = AppConfig.facebook['key']
twitter_key  = AppConfig.twitter['key']

Làm cách nào để đọc biến ENV trong config.yml, cấu hình của tôi giống nhau .. tôi đã thêm biến trong bashrc và tôi đang cố đọc biến đó trong config.yml bằng khóa: <% = ENV [URL]%> ... này không hoạt động
shiva

@shiva Nhìn vào đá quý Figaro cho các biến ENV. Thiết lập cấu hình này dành cho các giá trị không cần ẩn khỏi kiểm soát nguồn.
Shadoath

17

Tôi chỉ muốn cập nhật cái này cho những thứ hay ho mới nhất trong Rails 4.2 và 5, bây giờ bạn có thể làm điều này trong bất kỳ config/**/*.rbtệp nào của bạn :

config.x.whatever = 42

(và đó là một nghĩa đen xtrong đó, nghĩa là, nghĩa config.x.đen phải là như vậy, và sau đó bạn có thể thêm bất cứ điều gì bạn muốn sau x)

... và điều này sẽ có sẵn trong ứng dụng của bạn dưới dạng:

Rails.configuration.x.whatever

Xem thêm tại đây: http://guides.rubyonrails.org/configuring.html#custom-configuration


3
Chỉ cần làm rõ rằng ban đầu gây ra một vấn đề cho tôi; x không phải là một giữ chỗ cho bất cứ điều gì bạn muốn đặt, nó thực sự cần phải là chữ cái x.
tobinibot

Điểm tuyệt vời @tobinibot - Tôi đã thêm phần làm rõ vào câu trả lời của mình, cảm ơn.
smathy

Điều thú vị là các hướng dẫn thực sự không đề cập đến 'x', nhưng tôi có thể chứng thực rằng nó vẫn cần thiết kể từ Rails 5.0
Don

Bạn nói đúng Don, thật lạ - tôi chắc chắn nó đã từng nói như vậy.
smathy

1
Từ các tài liệu rails hiện tại: You can configure your own code through the Rails configuration object with custom configuration under either the config.x namespace, or config directly. The key difference between these two is that you should be using config.x if you are defining nested configuration (ex: config.x.nested.nested.hi), and just config for single level configuration (ex: config.hello).Nguồn: guide.rubyonrails.org/configuring.html#custom-configuration
David Gay

6

Chỉ cần một số thông tin thêm về chủ đề này:

APP_CONFIG = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env].with_indifferent_access

".With_indifferent_access" cho phép bạn truy cập các giá trị trong hàm băm bằng khóa chuỗi hoặc bằng khóa ký hiệu tương đương.

ví dụ.
APP_CONFIG['audiocast_uri_format'] => 'http://blablalba/blabbitybla/yadda' APP_CONFIG[:audiocast_uri_format] => 'http://blablalba/blabbitybla/yadda'

Hoàn toàn là một điều tiện lợi, nhưng tôi thích có các khóa của mình được biểu thị như các biểu tượng.


5

Tôi sử dụng một cái gì đó tương tự như John cho Rails 3.0 / 3.1, nhưng trước tiên tôi đã phân tích cú pháp tệp:

APP_CONFIG = YAML.load(ERB.new(File.new(File.expand_path('../config.yml', __FILE__)).read).result)[Rails.env]

Điều này cho phép tôi sử dụng ERB trong cấu hình của mình nếu tôi cần, như đọc url redistogo của heroku:

production:
  <<: *default
  redis:                  <%= ENV['REDISTOGO_URL'] %>

2
Tôi không nghĩ rằng tôi sẽ cần điều này mỗi ngày, nhưng đây là một giải pháp thực sự tuyệt vời cho những lúc bạn cần nó. Tôi nghĩ rằng tôi sẽ thay đổi tên tệp thành config.yml.erb mặc dù để phù hợp với quy ước rails.
Andrew Burns

2

Rails 4

Để tạo một cấu hình tùy chỉnh yaml và tải nó (và cung cấp cho ứng dụng của bạn) tương tự như cách database_configuration.

Tạo của bạn *.yml, trong trường hợp của tôi, tôi cần một tệp cấu hình redis.

config/redis.yml

default: &default
  host: localhost
  port: 6379

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default
  host: <%= ENV['ELASTICACHE_HOST'] %>
  port: <%= ENV['ELASTICACHE_PORT'] %>

Sau đó tải cấu hình

config/application.rb

module MyApp
  class Application < Rails::Application

    ## http://guides.rubyonrails.org/configuring.html#initialization-events
    config.before_initialize do
      Rails.configuration.redis_configuration = YAML.load_file("#{Rails.root}/config/redis.yml")
    end

  end
end

Truy cập các giá trị:

Rails.configuration.redis_configuration[Rails.env]để tương tự như thế nào bạn có thể có quyền truy cập vào database.ymlbằngRails.configuration.database_configuration[Rails.env]


Bạn cũng có thể tiết kiệm thời gian cho mình bằng cách chỉ thực hiện các cài đặt cho môi trường hiện tại của bạn, đây có lẽ là những thứ duy nhất bạn cần dù sao : Rails.configuration.redis_configuration = YAML.load_file("#{Rails.root}/config/redis.yml")[Rails.env]. Tuy nhiên, trong đường ray 4.2 trở lên , câu trả lời của smath có lẽ là một cách đơn giản hơn để đi.
omnikron

1

Dựa trên giải pháp tao nhã của Omer Aslam, tôi quyết định chuyển đổi các phím thành biểu tượng. Thay đổi duy nhất là:

all_config = YAML.load_file("#{Rails.root}/config/config.yml").with_indifferent_access || {}

Điều này cho phép bạn sau đó tham chiếu các giá trị bằng các ký hiệu dưới dạng các khóa, ví dụ:

AppConfig[:twitter][:key]

Điều này dường như gọn gàng hơn trong mắt tôi.

(Được đăng dưới dạng câu trả lời vì danh tiếng của tôi không đủ cao để nhận xét về câu trả lời của Omer)



0

xem phản hồi của tôi về đâu là nơi tốt nhất để lưu trữ các tham số ứng dụng: cơ sở dữ liệu, tệp, mã ...?

Một biến thể cho những gì bạn có trong đó là một tham chiếu đơn giản đến một tệp khác. Nó thấy rằng môi trường.rb không được cập nhật liên tục và không có nhiều thứ cụ thể cho ứng dụng trong đó. Mặc dù không phải là một câu trả lời cụ thể cho câu hỏi của bạn về "đó có phải là cách của Rails không?", Có lẽ sẽ có một số cuộc thảo luận về điều đó.


0

Tôi thích truy cập cài đặt thông qua ngăn xếp ứng dụng toàn cầu. Tôi tránh các biến toàn cầu dư thừa trong phạm vi địa phương.

cấu hình / khởi tạo / myconfig.rb

MyAppName::Application.define_singleton_method("myconfig") {YAML.load_file("#{Rails.root}/config/myconfig.yml") || {}}

Và truy cập nó với.

MyAppName::Application.myconfig["yamlstuff"]

0

Cách của tôi để tải Cài đặt trước khi khởi chạy Rails

Cho phép bạn sử dụng cài đặt trong khởi tạo Rails và định cấu hình cài đặt cho mỗi môi trường

# config/application.rb
Bundler.require(*Rails.groups)

mode = ENV['RAILS_ENV'] || 'development'
file = File.dirname(__FILE__).concat('/settings.yml')
Settings = YAML.load_file(file).fetch(mode)
Settings.define_singleton_method(:method_missing) {|name| self.fetch(name.to_s, nil)}

Bạn có thể nhận cài đặt theo hai cách: Cài đặt ['email'] hoặc Cài đặt.


0

Cách tốt nhất của tôi để cấu hình tùy chỉnh, với thông báo nâng cao khi thiếu.yml.

được tải từ trình khởi tạo tùy chỉnh trong config / khởi tạo / custom_config.rb

setting_config = File.join(Rails.root,'config','setting.yml')
raise "#{setting_config} is missing!" unless File.exists? setting_config
config = YAML.load_file(setting_config)[Rails.env].symbolize_keys

@APP_ID = config[:app_id]
@APP_SECRET = config[:app_secret]

Tạo một YAML trong config / settings.yml

development:
  app_id: 433387212345678
  app_secret: f43df96fc4f65904083b679412345678

test:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212

production:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212
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.