为我的 Rails 应用程序创建自定义配置选项的最佳方式?

我需要为我的 Rails 应用程序创建一个配置选项。对于所有的环境都是一样的。我发现,如果我把它设置为 environment.rb,它在我的视图中是可用的,这正是我想要的..。

environment.rb


AUDIOCAST_URI_FORMAT = http://blablalba/blabbitybla/yadda

效果很好。

然而,我有点不安。这样做好吗? 有没有更时髦的方法?

75100 次浏览

对于不需要存储在数据库表中的一般应用程序配置,我喜欢在 配置目录中创建一个 config.yml文件。对于你的例子,它可能看起来像这样:

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


development:
<<: *defaults


test:
<<: *defaults


production:
<<: *defaults

此配置文件从 配置/初始化器中的自定义初始值设定项加载:

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

如果您正在使用 Rails 3,请确保不要在相对配置路径中意外地添加前斜杠。

然后可以使用以下方法检索该值:

uri_format = APP_CONFIG['audiocast_uri_format']

有关详细信息,请参阅 这个铁路广播

我喜欢 简单配置。它允许你有每个环境的配置。

看看我对 哪里是存储应用程序参数的最佳位置: 数据库、文件、代码... ?的反应

一个变体,你有,它是一个简单的引用到另一个文件。它看到環.rb 不是不断更新的,而且里面没有一堆特定于 app 的东西。 尽管这并不是对“这是 Rails 的方式吗?”这个问题的具体回答?也许会有一些讨论。

RAILS 3版本的初始化程序代码如下(RAILS _ ROOT & RAILS _ ENV 不推荐)

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

此外,Ruby1.9.3使用 Psych,这使得合并键区分大小写,因此您需要更改配置文件以考虑到这一点,例如。

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


development:
<<: *DEFAULTS


test:
<<: *DEFAULTS


production:
<<: *DEFAULTS

我使用了一些类似于 John for Rails 3.0/3.1的东西,但是我首先对文件进行了 erb 解析:

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

这允许我在配置中使用 ERB,如果需要的话,比如阅读 heroku 的 redistogo URL:

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

关于这个话题的一些额外信息:

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

“ . with _ different _ access”允许您使用字符串键或等效的符号键访问散列中的值。

例如。
APP_CONFIG['audiocast_uri_format'] => 'http://blablalba/blabbitybla/yadda' APP_CONFIG[:audiocast_uri_format] => 'http://blablalba/blabbitybla/yadda'

纯粹是为了方便,但我更喜欢用符号来表示我的钥匙。

步骤1: 创建 config/initializer/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)

步骤2: Create config/config.yml

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


development:
<<: *common


test:
<<: *common


production:
<<: *common

步骤3: 获取代码中的任意位置的常量

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

我更喜欢通过全局应用程序堆栈访问设置。

Config/initializer/myconfig.rb

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

然后用。

MyAppName::Application.myconfig["yamlstuff"]

我只是想更新 Rails 4.2和 Rails 5中最新的酷玩意儿,你现在可以在任何 config/**/*.rb文件中这样做:

config.x.whatever = 42

(这是字面上的 x,即。字面上的 config.x.必须是,然后你可以添加任何你想后的 x)

你的应用程序里会有:

Rails.configuration.x.whatever

点此查看更多内容: http://guides.rubyonrails.org/configuring.html#custom-configuration

Rails 4

创建一个自定义配置 yaml 并加载它(并使应用程序可用) ,类似于 database_configuration

创建您的 *.yml,在我的情况下,我需要一个重排配置文件。

config/redis.yml

default: &default
host: localhost
port: 6379


development:
<<: *default


test:
<<: *default


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

然后加载配置

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

访问值:

类似于你可以通过 Rails.configuration.database_configuration[Rails.env]访问你的 database.yml

基于 Omer Aslam 优雅的解决方案,我决定把钥匙转换成符号,唯一的改变是:

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

这样你就可以通过符号引用值作为键,例如。

AppConfig[:twitter][:key]

我觉得这样比较干净。

(作为一个回答发布,因为我的声誉不够高,不足以评论 Omer 的回复)

Rails > = 4.2

只需在 config/目录中创建一个 YAML文件,例如: config/neo4j.yml

neo4j.yml的内容可以如下所示(为简单起见,我对所有环境都使用了默认值) :

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


development:
<<: *default


test:
<<: *default


production:
<<: *default

config/application.rb:

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

现在,您的自定义配置可以像下面这样访问:

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

更多信息

Rails 官方 API 文档将 config_for方法描述为:

为当前 Rails env 加载 config/foo.yml 非常方便。


如果不想使用 yaml文件

正如 Rails 官方指南所言:

您可以通过 Rails 配置对象在 config.x属性下使用自定义配置来配置自己的代码。

例子

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

然后这些配置点可以通过配置对象获得:

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

官方参考 config_for方法 | 官方铁路指南

在 Rails 初始化之前加载设置的方法

允许您在 Rails 初始化中使用设置并为每个环境配置设置

# 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)}

您可以通过两种方式获得设置: 设置[‘ em ail’] 或 < strong > Settings.email

我最好的自定义配置方法是在 seting.yml 丢失时使用引发消息。

从 config/initializer/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]

在 config/seting.yml 中创建 YAML

development:
app_id: 433387212345678
app_secret: f43df96fc4f65904083b679412345678


test:
app_id: 148166412121212
app_secret: 7409bda8139554d11173a32222121212


production:
app_id: 148166412121212
app_secret: 7409bda8139554d11173a32222121212