Victor
Victor

Reputation: 13388

DRYer application.yml for site-wide constants

Using Rails 3.2. I have the following:

# application.rb
APP_CONFIG = YAML.load(File.read(File.expand_path('../app_config.yml', __FILE__)))[Rails.env]

# application.yml
development: &non_production_settings
  site_url: http://goodboy.com
  site_name_lowercase: good boy
  site_name_titleize: Good Boy

production:
  site_url: http://goodboy.com
  site_name_lowercase: good boy
  site_name_titleize: Good Boy

First, I would like to set a site-wide configuration, but it's not able to find the constants:

site_name_lowercase: good boy
site_name_titleize: Good Boy

development: &non_production_settings
  site_url: http://goodboy.development

production:
  site_url: http://goodboy.com

Second, I know this is a YAML file, but is there anyway for me to use Rails method like this:

site_name_lowercase: good boy
site_name_titleize: site_name_lowercase.titleize

Upvotes: 0

Views: 529

Answers (1)

phoet
phoet

Reputation: 18845

victor, please have a look into how YAML works and what you can do with it. from what you are asking i can see that this would be a good thing for you.

it's always a good thing to read the specifications. for YAML those are actually pretty well done and readable: http://www.yaml.org/spec/1.2/spec.html#id2708649

to answer your questions:

firstly, if i understand you correctly, you want to have global configuration options in the YAML file that are not environment specific. in your case it is site_name_lowercase and site_name_titleize. both keys are at the toplevel of your YAML file, so there are totally unscoped.

if you look at the code that you are using for this:

YAML.load(File.read(File.expand_path('../app_config.yml', __FILE__)))[Rails.env]

it is clear that this approach can not work at all, as it takes the configuration with the scope of the Rails.env. so a really simple solution for that problem would be to put your global configuration under the key global:

global:
  site_name_lowercase: good boy
  site_name_titleize: Good Boy

development: &non_production_settings
  site_url: http://goodboy.development

production:
  site_url: http://goodboy.com

and just use it:

document   = YAML.load(File.read(File.expand_path('../app_config.yml', __FILE__)))
APP_CONFIG = document[Rails.env].merge(document['global'])

to answer your second question, no, it's not possible to write ruby code in YAML.

what you can do in rails is using ERB tags in YAML files to evaluate stuff. it's also possible to marshall objects into YAML. this is both probably not what you want.

in your case, i don't think that there is any point in that approach. this is not a good spot to generalize things. and if you really think that this is worth it, you can just write a helper method to create a titleized version and use it in your code.

Upvotes: 1

Related Questions