2010-11-10 76 views
24

我想补充两个额外的配置选项,以我的application.rb中,所以我可以在控制器的读出来。从控制器application.rb中访问配置(Rails 3中)

# Extra 
config.twitter.key = 'foo' 
config.twitter.secret = 'bar' 

我想用三个建议的方法来访问它们:

self.config.twitter.key # Should be extended through ApplicationController Base 
config.twitter.key # Inherited but with different syntax 
CONFIG['twitter']['key'] #some massive magical array that apparently exists somewhere 

他们全都给我不同的错误,当我通过他们通过“调试”的方法,如:

debug self.config.twitter.key # undefined method `key' for nil:NilClass 

那么,怎么回事?

回答

45

我相信你对config/application.rb提供给你的期望有点不正确。 ActiveRecord :: Base和ActiveController :: Base特征类使用在config/application.rb中配置的Rails :: Application :: Configuration类。这些属性在从基类或其特征类中下来的类中不可用。这就是您在ApplicationController中遇到错误的原因。

通常有两种方式来进行配置初始化的Rails应用程序。第一种方式是通过初始创建配置模块,然后负载值到其中:

首先,创建一个Twiter配置模块:

#lib/twitter_config.rb 
module TwitterConfig 
    def self.config 
    @@config ||= {} 
    end 

    def self.config=(hash) 
    @@config = hash 
    end 
end 

创建YAML配置文件:

# config/twitter.yaml 
development: &base 
    key: "foo" 
    secret: "bar" 

test: 
<<: *base 
key: "foo2" 

production: 
    <<: *base 
    secret: "barbar" 

或者,如果您不打算将config/twitter.yaml添加到您的SCM,则可以跳过此步骤并通过环境变量设置密钥和秘密。这将是在Heroku上部署公共SCM资源库的应用程序的建议解决方案。

然后加载并通过初始化设置的值:

#config/initializers/01_twitter.rb 
require 'twitter_config' 

TwitterConfig.config = YAML.load_file("config/config.yml")[Rails.env].symbolize_keys 

它通常是到号码您的初始化文件,Rails会,以便根据自己的文件名加载它们的最佳做法。如果您正在初始化数据存储并且对于其他步骤至关重要,那么它需要最低的数字。另外,如果您使用的环境变量,这将是init文件:

#config/initializers/01_twitter.rb 
require 'twitter_config' 

TwitterConfig.config[:key] = ENV['twitter_config_key'] 
TwitterConfig.config[:secret] = ENV['twitter_config_secret'] 

整个Rails应用程序,你现在有TwitterConfig.config访问配置值[:键] & TwitterConfig.config [:秘密]。你也可以包含模块,只要注意冲突。

您也可以将这些值加载为全局常量。这感觉有点丑到我虽然:

#config/application.rb 
TWITTER_CONFIG = YAML.load_file("config/twitter.yaml")[Rails.env] 
+2

血腥的好回答,非常感谢。 – 2010-11-10 14:56:34

+0

它重置变量为零在开发服务器! – 2011-05-20 00:00:14

+0

我在Ruby 1.9.2-p180上使用Rails 3.1应用程序时遇到了一些麻烦。在我的应用程序中,如果我要调用TwitterConfig.method,它只会给我一个错误。但是,如果我检查TwitterConfig.instance_methods,我可以清楚地看到定义的方法。 – Emerson 2011-11-03 03:09:02

5

你可能要考虑使用YAML文件的方法。

在application.rb中

CONFIG = YAML.load_file("config/config.yml")[Rails.env] 

在配置/ config.yml

development: &base_config 
    twitter_key = "foo" 
    twitter_secret = "bar" 

test: 
    <<: *base_config 
    twitter_key = "foo2" 

production: 
    <<: *base_config 
    twitter_secret = "barbar" 

相同的使用与以前与重载的环境电平定义的属性。

CONFIG['twitter_key'] 
+0

看起来不错,但如何我可以在application.rb中读取这些值吗?这不是他们的目的吗? – 2010-11-10 11:57:13

-1

只要把文件config/initializers/app_config.rb如果使用ENV不变,你可以稍后轻松地部署到Heroku的与heroku config:add twitter_key=mypublickey命令设置的值。

事情是这样的:

## config/initializers/app_config.rb 
unless Rails.env.production? 
    ENV['twitter_key'] = 'foo' 
    ENV['twitter_secret'] = 'bar' 
end 

你保持你的生产钥匙了版本控制,并且不需要与YAML的文件运球。

0

一个小更新到广泛接受的答案在这里:Accessing config from application.rb in Controller (Rails 3)

模块TwitterConfig应该是类方法(或模块的方法,如果你喜欢这种方式)内的方法。它们不能是实例方法。

很抱歉,将此回答置于答案中,但我无法找到解答该答案的方法。

13

我试过这个,似乎工作,你可以使用:: Rails.application.config。

例如我用它来获得正确的TIME_ZONE在应用程序中设置这样的:

Rails.application.config.time_zone

我发现它感谢less- Rails代码:https://github.com/metaskills/less-rails/blob/master/lib/less/rails/helpers.rb

所以,你可以在你的application.rb中或在任何环境文件中声明这一点:

config.twitter_key = '富'

,然后阅读它就像在你的代码,以便在任何地方:

Rails.application.config.twitter_key

+0

两个冒号('::')似乎并不需要。 – 2015-01-27 02:17:27