Dynamic fields in YAML file.
Recently I had the need to setup environment specific .yml files for email configuration. Normally this goes off without a hitch, however in my case I had the additional requirement of being able to dynamically substitute values in the yml file at runtime. I thought it would be nice to allow configuration of email to, cc, bcc, subject and so forth through the yml file… thus allowing different environments to target different recipients. I first tried to access the model from the yml file…
recipient: <%= user.email_address %>
but to no avail. Seems like the mailer was loaded before the model so the user object was not yet available. A solution that I came up with, though kind of hacky, was to tokenize the yml with placeholders that are dynamically replaced by the mailer at runtime.
My .yml file now looks like this:
email_notifications:
activate:
from: acct_activations@company.com
recipients: @USER_EMAIL@
bcc: devuser@company.com
subject: Activate your new account (@USER_COMPANY@)
and in my mailer I added a method to do the replacement:
def replace_yaml_tokens(yaml_doc, user)
yaml_obj = YAML::dump( yaml_doc )
yaml_obj.gsub!(/\@USER_EMAIL\@/, user.email_address)
yaml_obj.gsub!(/\@USER_COMPANY\@/, user.company)
YAML::load( yaml_obj )
end
finally it was a simple call after initializing the mailer to do the replacement.
mailer=replace_yaml_tokens(YAML::load( File.open( "#{RAILS_ROOT}/config/activation.yml" ) )['email_notifications']['activate'], user);
Like I said, maybe not the best solution, but one that worked for me!