Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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.secret = 'bar' 

I am trying to access them using three suggested methods:

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 

They all give me different kinds of error when I pass them through the "debug" method, E.g:

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

So, whats going on?

like image 508
Phil Sturgeon Avatar asked Nov 10 '10 10:11

Phil Sturgeon


People also ask

Where is Rails application config?

You probably know that you can configure Rails in config/application. rb and config/environments/development. rb etc. But you can also leverage that for configuring your own custom settings for your application.

What is application RB in Rails?

The configuration file config/application. rb and environment-specific configuration files (such as config/environments/production. rb ) allow you to specify the various settings that you want to pass down to all of the components. For example, you could add this setting to config/application.rb file: config.

What is the purpose of environment RB and application RB file?

In the environment. rb file you configure these run-levels. For example, you could use it to have some special settings for your development stage, which are usefull for debugging. The purpose of this file is to configure things for the whole application like encoding.


1 Answers

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] 
like image 116
Patrick Robertson Avatar answered Oct 04 '22 00:10

Patrick Robertson