Handling properties/configurations in Rails - ruby-on-rails

I want to be able to move hard-coded configuration outside of my .rb files.
I don't want to have stuff like this:
config.action_mailer.default_url_options = {
:host => 'www.mydomain.com',
}
I need it to be easy to change between different machines.
What will be the best path to achieve that?
Thanks

Usually configuration stuff is intended to stay inside .rb files -- that's the best path to achieve different configurations in different environments.
So if you have a production environment and a beta environment, in beta.rb you'd have:
config.action_mailer.default_url_options = {
:host => 'beta.mydomain.com',
}
And in production.rb you'd have:
config.action_mailer.default_url_options = {
:host => 'www.mydomain.com',
}
If you're trying to store your configuration settings elsewhere, you're probably trying to vary the settings because your deployment environment isn't static (like EC2, where you could be bringing up and down machines constantly with different IPs). In that case, I'd recommend investigating a tool like rubber or chef that provide programmatic ways to transform configuration files.

Related

How to get environment configuration values in an ActionMailer class?

I want to place an image in emails to let me know if a person has opened the email. So the image will simply be a route in my rails app to a specific controller to handle that logic:
<img src="http://www.example.com/invitations/43/open.png" />
Problem is, http://www.example.com works in production, but we have different development and test environments. Is there a way to use an environment configuration value in the /config/environments Ruby files inside an ActionMailer template?
You could make use of the action_mailer.default_url_options if you set it in your config files (config/environnments/).
If you set in production.rb and developpment.rb like so
config.action_mailer.default_url_options = { host: 'www.example.com' }
You can call it anywhere using
Rails.application.config.action_mailer.default_url_options[:host]

How can I define environment variables locally and not change their definitions/push them to heroku?

I have many credentials that I have to handle in order to hook my app up to amazon s3 and other services.
I got my heroku app up and running with s3, and it works great. I defined my s3 access credentials following this example: http://devcenter.heroku.com/articles/config-vars
However, I want now to be able to have access to s3 from my local development environment. Obviously, the config vars that I defined on heroku aren't available on my localhost. How can I define these keys locally? Also, I'm looking in particular for a solution that is secure (for example if I define my keys in plain text in an intializer or something, I don't want that file to be pushed on heroku).
For background, here is what I add to my model to get paperclip running with s3
has_attached_file :photo,
:storage => :s3,
:bucket => 'bucket_name',
:s3_credentials => {
:access_key_id => ENV['S3_KEY'],
:secret_access_key => ENV['S3_SECRET']
}
The best place to define stuff like this, if you don't want it shared, is probably an initializer.
# config/initializers/s3_constants.rb
if Rails.env.development?
S3_KEY = "mys3key"
S3_SECRET = "mys3secret"
end
Ensure this file is added to .gitignore so it won't be pushed along with the rest of your repository.
Realistically speaking, constants that differ on a per-environment basis should really be located in the file for that environment (say development.rb here)... but those files should also really be added to your version control system, and if you definitely, definitely want this data excluded from git, then a separate file that you do not commit is probably your best bet.
Just define the environment variables in your .bash_profile file like any other environment variable. Maybe leave a comment to demarcate the section as Rails-specific environment variables.
#~/.bash_profile
# Rails constants
S3_KEY="blady"
S3_SECRET="bladybloo123"
Also, maybe you want to change the name to something more specific so that you can have more than one s3 connection defined...
heroku provides heroku config:add and you provide KEY=value. see config vars documentation

Rails & Devise: how to configure mail with domain name automatically?

I need some advice on configuring mail in production Ruby-on-Rails sites.
I deploy my Rails app on EngineYard. I have a couple of sites, like demo.mydomain.com or staging.mydomain.com - how can I configure Devise so that at deploy time I can make sure confirmation mails come from demo.mydomain.com or staging.mydomain.com automatically? ie, I want the same GitHub codebase, and want to fill the configuration in dynamically.
Currently in config/environments/production.rb I have the line:
config.action_mailer.default_url_options = { :host => 'demo.mydomain.com' }
But that's incorrect when the same code is deployed to staging.mydomain.com as they both run in RAILS_ENV=production
Any ideas?
Thanks,
Dave
Update: For now, to be practical, I've added specific environments to hardcode the mailer domain. So now demo.mydomain.com runs on environments/demo.rb, and www.mydomain.com runs on environments/productions.rb. What I don't like about this is the duplication between the files, it's not clear to me how to DRY them up as I have with, eg, database.yml
in your devise configuration, usually config/initializers/devise.rb you can configure the mail-sender for devise. this configuration takes a proc, so that it's possible to evaluate something at runtime.
Devise.setup do |config|
config.mailer_sender = Proc.new { your_magic_here }
end
Ideally staging & production servers should run on different rails environment. Still if you wanted to have production env running on both staging & production servers with different action mailer urls then it should be done at deployment level. You can always write environment file while deployment.
First of all, I think you should separate the environments of your application. Check this guide to learn how you can do it.
Then, try something like this in your devise configuration:
Devise.setup do |config|
if Rails.env.production?
config.mailer_sender = "no-reply#domain.com"
elsif Rails.env.staging?
config.mailer_sender = "no-reply#staging.domain.com"
else
config.mailer_sender = "no-reply#domain.com"
end
...
Check this guide to understand more about Proc object.

What is the "best practices" approach to setting up custom global email defaults in Rails?

I'm starting a new Rails 3 app from scratch.
And as I was going through basic setup ( configuring gems, sessions, etc) I ran into something that has been nagging me for a while.
Our current system ( a mixture of Ruby scripts & Rails 2 app) send various email / fax notifications to clients. There are certain things that are common in 80% of cases - cc - certain email accounts on our end and email signature.
Previously I just defined GLOBALS in the environment.rb such as
SYSTEM_EMAIL_SIGNATURE
or
SYSTEM_EMAIL_NOTIFY
and used them later in mailers or if it was a stand-alone script I had a setup.rb file - that had a bunch of common settings - including a has with custom email settings like this.
Since I'm rebuilding this app from scratch and consolidating all scripts into one ruby app - I was trying to think of a better way to do this.
Right now I'm setting up an email.rb Initializer that has action_mailer settings, that I extended by adding a few more items:
########## Setup Global Email Defaults ##############
Site::Application.configure do
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => 'mail.example.com',
:port => 25,
:domain => 'example.com',
# These are custom to OUR setup - used later in the code
:default_from => 'it.systems#example.com',
:default_notify => ["it.manager#example.com"],
:default_signature => "
---------------------------
This is an automatic email.
If you have any questions please contact customer service
at 1 (800) 888-0000 or go to http://www.example.com.
Thank you for your business!"
}
end
So is this a good approach? Or is there a better way then these two approaches?
I think you're on the right track for default_from and default_notify.
I wouldn't use SMTP settings for that; those aren't SMTP settings, they're just general mailer settings.
I'd go with something like this in an initializer:
MAILER_SETTINGS = YAML::load(open(File.join(Rails.root, "config", "mailer.yml")).read)[Rails.env]
With a yaml file that looks like this:
development: &development
default_from: foo#bar.com
default_notify: ["foo#bar.com"]
production:
<<: *development
default_from: production#bar.com
That lets you set defaults, then cascade them down and override per-environment as desired.
However, for the signature, I'd just move that into a partial, which you then include in your mail templates. They're views like any other and can have layouts, partials, and all of that.

Storing configuration variable in ruby on rails

I'm storing configuration variables for different environments in the production.rb and development.rb
production.rb
ENV['my_variable'] = 'val1'
development.rb
ENV['my_variable'] = 'val2'
Maybe exists another way to store variables for different environments. What is the best way?
I've been pointing people towards the settingsgem lately. Settings Gem

Resources