views:

200

answers:

6

Hello.

I was wondering if there is the best practice on where to store global settings in a rails app. What I mean by that is i.e: I have a few globals defined that may change, but not likely and it seems inappropriate to store them in DB since they are used so much. For instance I have SYSTEM_EMAIL & SYSTEM_EMAIL_SIGNATURE & SYSTEM_STORAGE_ROOT.

Right now I keep them in environment.rb, but I'm not sure if this is the right palce to store them.

Thank you

+1  A: 

environment.rb is the place. You can add it to a Module and add it to the lib directory. then you could call it as Module::MY_GLOBAL_VARIABLE. Both has strong points and weak points. In the environment.rb is ok but sometimes it looks messy. If all those global variables are related, you can group then in a module.

VP
+2  A: 

Rails 3 introduces the Application object. Even with Rails 2, you might want to store your globals in a similar manner.

Marc-André Lafortune
Interesting, I started looking at Rails 3 recently - specifically routes, but haven't read much else. I will take a look. Thanks for the pointer Marc
Nick Gorbikoff
+2  A: 

Because such values often change depending on the environment you're running in, I store globals in config/environments/development.rb|production.rb|test.rb, with appropriate values for each environment.

Ben
+1  A: 

I store such configuration information in a YML file. Refer to this screen-cast for more details.

Alternatively you can use a gem called app_config.

KandadaBoggu
+2  A: 

One of my favourite techniques is to put a file containing the constants in directory config/initializers/ (all files in this directory are loaded automatically) but with a section for each different Rails environment. e.g.


case ENV['RAILS_ENV']
  when "development"
    SYSTEM_EMAIL = ...
    SYSTEM_EMAIL_SIGNATURE = ...
  when "staging"
    SYSTEM_EMAIL = ...
    SYSTEM_EMAIL_SIGNATURE = ...
  when "production"  
    SYSTEM_EMAIL = ...
    SYSTEM_EMAIL_SIGNATURE = ...
end

If you want, instead, to load up all the constants in one big hash then you can load them as a YAML file. Create two files, one called, say, config/initializers/email_constants.rb and the other config/email_constants.yml. In the latter put something like:


development:
  :system_email: ...
  :system_email_signature: ...
staging:
  :system_email: ...
   system_email_signature: ...

... etc ...

Then in config/initializers/email_constants.rb put:


EMAIL_CONSTANTS = YAML.load_file("#{RAILS_ROOT}/config/email_constants.yml")[RAILS_ENV]

This loads the entire YAML file and the assigns the value of the appropriate key (which represents the RAILS_ENV) to EMAIL_CONSTANTS.

The advantage of both of these techniques is locality. You can place all the constants that are related to each other (i.e. email constants in this case) in one file. Also, instead of having the same constants spread across three different files (one for each Rails environment) you have them all in one file.

Sean Seefried
Thank you Sean. I like you approach the most - except I don't think I need to separate into email_constants.yml - I'll just keep everything in contacnts.yml
Nick Gorbikoff
+1  A: 

Hi Nick

Normally when I'm doing something like this, I have two ways of doing this

1 - If my global variables are common to all 3 environments (development, test, production) , then i will store it in

config/environments.rb file

But lets say my values are changing upon the environment

Ex: my development environment SYSTEM_STORAGE_ROOT is '/development_root/' and testing environment SYSTEM_STORAGE_ROOT is '/testing_root/'

then I will store them inside

config/environments/

As per the above example

config/environments/development.rb will have SYSTEM_STORAGE_ROOT = '/development_root/'

config/environments/test.rb will have SYSTEM_STORAGE_ROOT = '/testing_root/'

config/environments/production.rb will have SYSTEM_STORAGE_ROOT = '/production_root/'

hope this helps,

cheers, sameera

sameera207