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

Posted

技术标签:

【中文标题】为我的 Rails 应用程序创建自定义配置选项的最佳方式?【英文标题】:Best way to create custom config options for my Rails app? 【发布时间】:2010-10-10 04:53:53 【问题描述】:

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

environment.rb

AUDIOCAST_URI_FORMAT = http://blablalba/blabbitybla/yadda

效果很好。

但是,我有点不安。这是一个好方法吗?有没有更时髦的方法?

【问题讨论】:

【参考方案1】:

对于不需要存储在数据库表中的一般应用程序配置,我喜欢在 config 目录中创建一个config.yml 文件。对于您的示例,它可能如下所示:

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

development:
  <<: *defaults

test:
  <<: *defaults

production:
  <<: *defaults

此配置文件从 config/initializers 中的自定义初始化程序加载:

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

详情请参阅this Railscast。

【讨论】:

您可能需要YAML::ENGINE.yamler = 'syck' 才能使用***.com/a/6140900/414220 仅供参考,在 Rails 3.x 中,您需要将 RAILS_ENV 替换为 Rails.env 并将 RAILS_ROOT 替换为 Rails.root 对于 Rails 3+,您应该加入相对路径,而不是绝对路径。不要在配置目录前加上斜线。 不确定以前的版本,但在 Rails 4.1 中你可以Rails.application.config.whatever_you_want = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env] @iphone007 确实可以从 config 目录加载任意 yaml 文件。请参阅下面的smathy's answer,我认为现在应该是公认的答案。【参考方案2】:

Rails 3 版本的初始化代码如下(RAILS_ROOT & RAILS_ENV 已弃用)

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

此外,Ruby 1.9.3 使用 Psych 使合并键区分大小写,因此您需要更改配置文件以将其考虑在内,例如

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

development:
  <<: *DEFAULTS

test:
  <<: *DEFAULTS

production:
  <<: *DEFAULTS

【讨论】:

你不需要"#Rails.root.to_s"; "#Rails.root" 工作。 我推荐Rails.root.join('config', 'config.yml') 而不是"#Rails.root.to_s/config/config.yml" 而且,我推荐使用:AppName::Application.config.custom,而不是 APP_CONFIG David,您的前两个 cmets 是最佳实践,我将修改代码,但最后一个我将省略,因为这意味着您需要记住每次使用时更改 AppName这段代码。【参考方案3】:

导轨 >= 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 环境加载 config/foo.yml。


如果您不想使用yaml 文件

正如 Rails 官方指南所说:

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

示例

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

Official Reference for config_for method | Official Rails Guide

【讨论】:

【参考方案4】:

第 1 步: 创建 config/initializers/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 步: 创建 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.yml 中读取 ENV 变量,我的配置是相同的 ..我在 bashrc 中添加了变量,我试图在 config.yml 中使用键读取它:...这不起作用 @shiva 查看 Figaro gem 中的 ENV 变量。此配置设置适用于不需要从源代码管理中隐藏的值。【参考方案5】:

我只是想为 Rails 4.2 和 5 中的最新酷东西更新此内容,您现在可以在您的任何 config/**/*.rb 文件中执行此操作:

config.x.whatever = 42

(那是一个文字x,即config.x. 字面意思必须是那个,然后你可以在x 之后添加任何你想要的东西)

...这将在您的应用中以如下形式提供:

Rails.configuration.x.whatever

在此处查看更多信息:http://guides.rubyonrails.org/configuring.html#custom-configuration

【讨论】:

只是一个最初给我造成问题的澄清; x 不是您要输入的任何内容的占位符,它确实需要是字母x 好点@tobinibot - 我已经在我的回答中添加了澄清,谢谢。 有趣的是指南实际上没有提到“x”,但我可以证明它仍然是必要的 Rails 5.0 你说得对,唐,这很奇怪——我敢肯定它曾经这么说。 来自当前的 rails 文档: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). 来源:guides.rubyonrails.org/configuring.html#custom-configuration【参考方案6】:

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

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

".with_indifferent_access" 允许您使用字符串键或等效符号键访问散列中的值。

例如。APP_CONFIG['audiocast_uri_format'] =&gt; 'http://blablalba/blabbitybla/yadda' APP_CONFIG[:audiocast_uri_format] =&gt; 'http://blablalba/blabbitybla/yadda'

纯粹是为了方便,但我更喜欢将我的键表示为符号。

【讨论】:

【参考方案7】:

我在 Rails 3.0/3.1 中使用类似于 John 的东西,但我先 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'] %>

【讨论】:

我不认为我每天都需要这个,但对于那些确实需要它的时候来说,这是一个非常酷的解决方案。我想我会将文件名更改为 config.yml.erb 以匹配 Rails 约定。【参考方案8】:

Rails 4

创建自定义配置 yaml 并加载它(并提供给您的应用),类似于 database_configuration

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

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.redis_configuration[Rails.env] 类似于您如何通过Rails.configuration.database_configuration[Rails.env] 访问您的database.yml

【讨论】:

您还可以通过仅针对当前环境进行设置来节省一些时间,这可能是您唯一需要的设置:Rails.configuration.redis_configuration = YAML.load_file("#Rails.root/config/redis.yml")[Rails.env]。但是在 rails 4.2 及更高版本中,smathy's answer 可能是一种更简单的方法。【参考方案9】:

基于 Omer Aslam 的优雅解决方案,我决定将键转换为符号。唯一的变化是:

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

这允许您通过符号作为键来引用值,例如

AppConfig[:twitter][:key]

这在我看来更整洁。

(作为答案发布,因为我的声誉不够高,无法评论 Omer 的回复)

【讨论】:

【参考方案10】:

我喜欢simpleconfig。它允许您对每个环境进行配置。

【讨论】:

【参考方案11】:

查看我对Where is the best place to store application parameters : database, file, code...?的回复

与您所拥有的不同,它是对另一个文件的简单引用。它看到 environment.rb 没有不断更新,并且其中没有一堆应用程序特定的东西。 虽然没有具体回答您的问题“它是 Rails 方式吗?”,但也许会有一些讨论。

【讨论】:

【参考方案12】:

我更喜欢通过全局应用程序堆栈访问设置。我避免在本地范围内使用过多的全局变量。

config/initializers/myconfig.rb

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

并使用它访问它。

MyAppName::Application.myconfig["yamlstuff"]

【讨论】:

【参考方案13】:

我在 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)

您可以通过两种方式获取设置: Settings['email']Settings.email

【讨论】:

【参考方案14】:

我自定义配置的最佳方式,在缺少 setting.yml 时会显示消息。

从 config/initializers/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/setting.yml 中创建 YAML

development:
  app_id: 433387212345678
  app_secret: f43df96fc4f65904083b679412345678

test:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212

production:
  app_id: 148166412121212
  app_secret: 7409bda8139554d11173a32222121212

【讨论】:

以上是关于为我的 Rails 应用程序创建自定义配置选项的最佳方式?的主要内容,如果未能解决你的问题,请参考以下文章

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

Rails update() 方法导致自定义 URL 错误

自定义 rails 配置部分

Ruby/Rails:您如何自定义 Devise 的邮件模板?

Ruby/Rails:您如何自定义 Devise 的邮件模板?

如何在 Rails 中定义自定义配置变量