Rails 3.1 Application Wide Variables
Note: This technique is basically ripped directly from a Stack Overflow question. All credit should go to Patrick Robertson who crafted a great answer.
Step 1 - Create an ApplicationSettings Module
Create a file within your application's lib directory. In my example, I create a file at: my-awesome-app/lib/application_settings.rb. This file will contain a very simple module that handles getting and setting our settings. It uses a neat technique where you create a "module_function," which is essentially an instance variable, but for modules. To start, we create our ApplicationSettings module, which handles getting and setting our config hash.
# ApplicationSettings # ======================== # Handles getting and setting our main application wide config hash. module ApplicationSettings # Returns our config hash, or if empty, returns an empty hash def config @@config ||= {} end # Sets our config class variable, which we expect to be a hash def config=(hash) @@config = hash end # Awesome. Allows us to use instance methods on a Module. # eg. ApplicationSettings.config module_function :config=, :config end
Step 2 - Create a Settings File
Those of us in the Ruby community like to make heavy use of YAML configuration files. Their syntax is beautiful and they are easy to parse. Like you might have gussed, these types of files are generally stored within your config directory (eg. my-awesome-app/config/application_settings.yml). My file looks something like this:
# application_settings.yml # ======================== # This file is used to setup an application wide hash that can # easily enable or disable specific feature sets. Any settings declared # in this YAML file should be directly available in the ApplicationSettings class. development: user_registration: true email_notifications: false test: user_registration: true email_notifications: true production: user_registration: false email_notifications: true
Step 3 - Tell Rails to Load Your Module and YAML File
At this point the files we created above are doing nothing because we still need to tell Rails to load them up. A nice way of doing this is by using an initializer, which is automatically loaded when Rails starts up. During initialization, Rails will load any files in the config/initializers directory (in alphabetical order).
In this example it works out well that our filename is actually "application_settings.rb", but you can always prefix your filename with a number (eg. 01_ze_file_name.rb) to have Rails load it first. My file is located at: my-awesome-app/config/initializers/application_settings.rb and contains the following:
# config/initializers/application_settings.rb # ======================== # Tells Rails to load our ApplicationSettings module and then # populates our config class variable with data from our application_settings.yml file # From here on in, we should be able to call: # # ApplicationSettings.config['email_notifications'] # # and have it return our config option... require "#{Dir.pwd}/lib/application_settings.rb" ApplicationSettings.config = YAML.load_file("config/application_settings.yml")[Rails.env]
Step 4 - Use it!
If everything is setup properly, you should now be able to access your settings from anywhere with your application by simply refering to: ApplicationSettings.config['email_notifications']. I hope you find this little snippet as helpful as I have. Application wide variables are certainly handy to have in your Rails toolkit.