代码之家  ›  专栏  ›  技术社区  ›  Phil Sturgeon

从控制器中的application.rb访问配置(Rails 3)

  •  24
  • Phil Sturgeon  · 技术社区  · 14 年前

    我试图在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 回复  |  直到 14 年前
        1
  •  45
  •   Sambhav Sharma    8 年前

    我相信您对config/application.rb的期望值背后有一个稍微不正确的想法。ActiveRecord::Base和ActiveController::Base特征类使用在config/Application.rb中配置的Rails::Application::Configuration类。这些属性在从任何一个基类或其特征类派生的类中都不可用。这就是为什么在ApplicationController中遇到错误。

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

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

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

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

    也可以将值作为全局常量加载。但我觉得有点难看:

    #config/application.rb
    TWITTER_CONFIG = YAML.load_file("config/twitter.yaml")[Rails.env]
    
        2
  •  13
  •   brutuscat    9 年前

    我已经试过了,而且似乎正在工作,您可以使用::Rails.application.config。

    Rails.application.config.时区

    我找到它多亏了less rails代码: https://github.com/metaskills/less-rails/blob/master/lib/less/rails/helpers.rb

    config.twitter_key='foo'

    然后在代码中的任何地方像这样阅读:

    Rails.application.config.twitter密钥

        3
  •  5
  •   David Lyod    14 年前

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

    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']
    
        4
  •  0
  •   Community agent420    7 年前

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

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

        5
  •  -1
  •   Ingemar    14 年前

    把文件放进去 config/initializers/ 喜欢 app_config.rb 如果您使用ENV constant,您可以稍后轻松地部署到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文件。