Accessing config from application.rb in Controller (Rails 3)

前端 未结 5 1053
情书的邮戳
情书的邮戳 2020-12-23 10:47

I\'m trying to add two extra config options to my application.rb so I can read them out in controllers.

# Extra
config.twitter.key = \'foo\'
config.twitter.s         


        
相关标签:
5条回答
  • 2020-12-23 10:49

    I believe you've got a slightly incorrect idea behind what your expectations for the config/application.rb is providing you. The ActiveRecord::Base and ActiveController::Base eigenclasses use the Rails::Application::Configuration class that is configured in config/application.rb. The attributes aren't available in classes that descend from either of the Base classes, nor their eigenclasses. This is why you are running into errors in ApplicationController.

    There are generally two ways to make configuration initializations in a Rails app. The first way is to create a configuration module and then load values into it via initializer:

    First, create a Twiter Config module:

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

    Create a YAML config file:

    # config/twitter.yaml
    development: &base
      key: "foo"
      secret: "bar"
    
    test:
     <<: *base
     key: "foo2"
    
    production:
      <<: *base
      secret: "barbar"
    

    Alternatively, if you don't intend to add config/twitter.yaml to your SCM, you can just skip this and set the key and secret via environment variables. This would be the suggested solution for an application with a public SCM repository deploying on Heroku.

    Then load and set the value via an initializer:

    #config/initializers/01_twitter.rb
    require 'twitter_config'
    
    TwitterConfig.config = YAML.load_file("config/config.yml")[Rails.env].symbolize_keys
    

    It's generally a best practice to number your initializer files as Rails will load them in order according to their filename. If you are initializing a datastore and that is critical for other steps, then it needs the lowest number. Alternatively, if you are using environment variables, this would be the init file:

    #config/initializers/01_twitter.rb
    require 'twitter_config'
    
    TwitterConfig.config[:key] = ENV['twitter_config_key']
    TwitterConfig.config[:secret] = ENV['twitter_config_secret']
    

    Throughout the Rails application, you now have access to the config values with TwitterConfig.config[:key] & TwitterConfig.config[:secret]. You can include the module as well, just watch out for conflicts.

    You can also just load the values as a global constant. It feels a bit ugly to me though:

    #config/application.rb
    TWITTER_CONFIG = YAML.load_file("config/twitter.yaml")[Rails.env]
    
    0 讨论(0)
  • 2020-12-23 10:53

    You might want to consider using a yaml file approach.

    In application.rb

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

    In config/config.yml

    development: &base_config
        twitter_key = "foo"
        twitter_secret = "bar"
    
    test:
      <<: *base_config
        twitter_key = "foo2"
    
    production:
      <<: *base_config
        twitter_secret = "barbar"
    

    Same usage as before with definable attributes on an environment level with overloading.

    CONFIG['twitter_key']
    
    0 讨论(0)
  • 2020-12-23 11:05

    Just put a file in config/initializers/ like app_config.rb If you use ENV constant you can later on easily deploy to Heroku setting the values with the heroku config:add twitter_key=mypublickey command.

    Something like this:

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

    You keep your production keys out of revision control and don't need to dribble with YAML-files.

    0 讨论(0)
  • 2020-12-23 11:11

    I've tried this and seems to be working, you can use ::Rails.application.config.

    For example I'm using it to get the correct time_zone set in the application like this:

    Rails.application.config.time_zone

    I found it thanks to the less-rails code: https://github.com/metaskills/less-rails/blob/master/lib/less/rails/helpers.rb

    So you can declare this in your application.rb or in any enviroment file:

    config.twitter_key = 'foo'

    And then read it like so anywhere in your code:

    Rails.application.config.twitter_key

    0 讨论(0)
  • 2020-12-23 11:15

    A small update to the widely accepted answer here : Accessing config from application.rb in Controller (Rails 3)

    The methods inside the module TwitterConfig should be class methods (or module methods if you prefer it that way). They can't be instance methods.

    Sorry to put this in an answer, but I could not find a way to comment on that answer.

    0 讨论(0)
提交回复
热议问题