从Controller(Rails 3)中的application.rb访问配置

时间:2010-11-10 10:49:04

标签: ruby-on-rails ruby ruby-on-rails-3

我正在尝试向application.rb添加两个额外的配置选项,以便我可以在控制器中读取它们。

# 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

那么,最近怎么回事?

5 个答案:

答案 0 :(得分:45)

我相信你对config / application.rb的期望背后有一点不正确的想法。 ActiveRecord :: Base和ActiveController :: Base特征类使用在config / application.rb中配置的Rails :: Application :: Configuration类。这些属性在从任何一个Base类或它们的本征类下降的类中都不可用。这就是您在ApplicationController中遇到错误的原因。

通常有两种方法可以在Rails应用程序中进行配置初始化。第一种方法是创建配置模块,然后通过初始化程序将值加载到其中:

首先,创建一个Twiter Config模块:

#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 [:key]&amp ;;访问配置值。 TwitterConfig.config [:秘密。您也可以包含该模块,只需注意冲突。

您也可以将值作为全局常量加载。不过对我来说感觉有点难看:

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

答案 1 :(得分:13)

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

例如,我正在使用它来在应用程序中设置正确的time_zone,如下所示:

  

Rails.application.config.time_zone

我发现它归功于少量代码:https://github.com/metaskills/less-rails/blob/master/lib/less/rails/helpers.rb

因此,您可以在application.rb或任何环境文件中声明:

  

config.twitter_key ='foo'

然后在代码中的任何地方读取它:

  

Rails.application.config.twitter_key

答案 2 :(得分:5)

您可能需要考虑使用yaml文件方法。

在application.rb

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

在config / 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']

答案 3 :(得分:0)

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

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

很抱歉把它放在答案中,但我找不到对这个答案发表评论的方法。

答案 4 :(得分:-1)

只需将文件放入config/initializers/ app_config.rb如果使用ENV常量,稍后可以使用heroku config:add twitter_key=mypublickey命令轻松部署到Heroku设置值。

这样的事情:

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

您的生产密钥不受版本控制,也不需要运行YAML文件。