Why wouldn't a specific environment override environment.rb in rails here? - ruby-on-rails

I'm trying to work on a Rails site here in it's development environment, where I want to test email delivery, and I can't work out why properties declared in the main environment.rb aren't being overwritten by the more specific development.rb file that I presume would be loaded when booting a rails app.
My understanding here is that values in more specific environment config files like this should override the shared 'environment.rb' config file, so if I have declared some email settings like so in config/environment.rb...
ActionMailer::Base.smtp_settings = {
:address => 'smtp.hostingcompany.com',
:port => 25,
:domain => 'productiondomain.net',
:authentication => :login,
:user_name => "productiondomainmailer",
:password => "TOP_SEKRIT"
}
... then code here in config/environments/development.rb below should override the ActionMailer:Base.smtp_settings hash:
ActionMailer::Base.smtp_settings = {
:domain => 'developmentdomain.net'
}
However, when load the app in the development environment, or from script/console to check the value of ActionMailer::Base.smtp_settings[:domain], it's still listed as 'productiondomain.net'.
Why might this happening?

To set the configuration for your development environment put:
config.action_mailer.smtp_settings =
rather than:
ActionMailer::Base.smtp_settings =
in config/environments/development.rb
Note that in config/environments/development.rb you will need to specify the full set of settings and not just :domain as the hash overwrites the existing value rather than being merged with it.
And similarly, set the default in config/environments.rb by putting config.action_mailer.smtp_settings = inside the Rails::Initializer.run do |config| block.

This should work:
config.action_mailer.smtp_settings = {
:address => 'smtp.some_host.com',
:port => 25,
:domain => 'developmentdomain.net',
:authentication => :login,
:user_name => 'blabla',
:password => "some_pass"
}

Related

Missing host to link to Rails heroku production

I have an app that I am trying to put onto production. When the user signs up they have an activation email that should be sent to their email accounts but I am getting stopped with this error:
ActionView::Template::Error(Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true)
The problem with this error is that I have everything set up correctly in my files. For example my production.rb file inside my environments folder looks like this:
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = { :host => 'secret-everglades-54128.heroku.com'}
ActionMailer::Base.smtp_settings = {
:address => 'smtp.sendgrid.net',
:port => '587',
:authentication => :plain,
:user_name => ENV['SENDGRID_USERNAME'],
:password => ENV['SENDGRID_PASSWORD'],
:domain => 'heroku.com',
:enable_starttls_auto => true
}
My enviorments.rb file looks like this:
# Load the Rails application.
require_relative 'application'
# Initialize the Rails application.
Rails.application.initialize!
config.action_mailer.default_url_options = { :host => 'secret-everglades-54128.heroku.com'}
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
This does not make any sense to me whatsoever, if anyone could shed some light on this problem I will be very great full.
The problem was that I had errors still concuring when I ran the command
git push heroku master
The problem was that I had my host set in the actually environment.rb file which wasn't needed so I removed that and once I did that I was able to get everything to work.

Rails 4 action_mailer host

For Rails 4, I am using config.action_mailer.asset_host = "http://localhost:3000" in
config > environments > development.rb
to load assets to my mailer.
Is there a better value than a hardcoded url? I imagine there should be one since I would not use this value in my production.rb. What is the code to find the current host url in rails config?
If you deploy to a known host, you can put it directly in production.rb
But if you really need to read it from the url, than you check this out
http://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-original_url
If you're using SendGrid, inside config/environment.rb file specify your ActionMailer settings to point to SendGrid’s servers.
ActionMailer::Base.smtp_settings = {
:user_name => 'your_sendgrid_username',
:password => 'your_sendgrid_password',
:domain => 'yourdomain.com',
:address => 'smtp.sendgrid.net',
:port => 587,
:authentication => :plain,
:enable_starttls_auto => true
}

Load rails app config from database

I'd like to load some config settings from the database when my Rails (3.2.13) app starts:
class MyApp < Rails::Application
#...normal config here...
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => SystemSetting.system_smtp_host,
:port => SystemSetting.system_smtp_port,
:user_name => SystemSetting.system_smtp_username,
:password => SystemSetting.system_smtp_password,
:authentication => SystemSetting.system_smtp_authentication,
:enable_starttls_auto => SystemSetting.system_smtp_enable_starttls_auto }
end
But it appears that the database config has not been read at this point. I get an error:
ActiveRecord::ConnectionNotEstablished (ActiveRecord::ConnectionNotEstablished)
How can I accomplish this? Either make Rails initialize the database config first, or ... something else?
Regarding practices: Doing stuff like this can be problematic because your application relies on your database to be full when in fact it should support an empty database. Two examples that I can think of are when you try to create a database from scratch (e.g. rake db:setup), or in tests environments.
However, if have no other choice: I would move the mailer initialization to your system_setting.rb or an initializer (where you are guaranteed to have a connection).
config/initializers/load_system_settings.rb
MyApp::Application.config.action_mailer.raise_delivery_errors = true
MyApp::Application.config.action_mailer.delivery_method = :smtp
MyApp::Application.config.action_mailer.smtp_settings = {
:address => SystemSetting.system_smtp_host,
:port => SystemSetting.system_smtp_port,
:user_name => SystemSetting.system_smtp_username,
:password => SystemSetting.system_smtp_password,
:authentication => SystemSetting.system_smtp_authentication,
:enable_starttls_auto => SystemSetting.system_smtp_enable_starttls_auto
}
Manually connect and load values from database.
class Application < Rails::Application
# Set your app path
app_base = 'MY_APPLICATION_PATH'
# Load db configs
db_yml = YAML.load_file("#{app_base}/config/database.yml")["production"]
# Establish db connection
ActiveRecord::Base.establish_connection(:adapter=>db_yml['adapter'], :database=>db_yml['database'], :username=>db_yml['username'], :password=>db_yml['password'])
# load model if not
require "#{app_base}/app/model/system_setting.rb" unless defined?('SystemSetting')
#...normal config here...
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => SystemSetting.system_smtp_host,
:port => SystemSetting.system_smtp_port,
:user_name => SystemSetting.system_smtp_username,
:password => SystemSetting.system_smtp_password,
:authentication => SystemSetting.system_smtp_authentication,
:enable_starttls_auto => SystemSetting.system_smtp_enable_starttls_auto }
#close sql connection after loaded
ActiveRecord::Base.connection.close
end

How do I setup different ActionMailer Base smtp settings for development and production?

I have ActionMailer working correctly in both production and development. I use different smtp settings for each environment, gmail for development and a SendGrid account through Heroku for production. I manually switch the settings in the setup_mail.rb file to work in development and then switch them back before pushing into production. This prevents my gmail password from becoming public on github as the SendGrid/Heroku settings do not require my password in the file:
development setup_mail.rb
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "mysite.com",
:user_name => "me#mysite.com",
:password => 'mypassword',
:authentication => "plain",
:enable_starttls_auto => true
}
production setup_mail.rb
ActionMailer::Base.smtp_settings = {
:address => 'smtp.sendgrid.net',
:port => '587',
:authentication => :plain,
:user_name => ENV['SENDGRID_USERNAME'],
:password => ENV['SENDGRID_PASSWORD'],
:domain => 'heroku.com'
}
ActionMailer::Base.delivery_method = :smtp
I am concerned that I will accidentally push the development settings with my password to github. I'd like to stop switching settings manually to prevent this from happening. How do I setup different ActionMailer Base smtp settings for development and production? Thanks
Have this setting in production.rb and development.rb, instead of having your password hard coded, you could use environment variables locally too, create a .env file in your project, which will be loaded when you cd in:
EMAIL=me#mysite.com
EMAIL_PASSWORD= mypassword
Use ENV['EMAIL'] AND ENV['EMAIL_PASSWORD'] in development.rb

Use constant declared in Initializer in Environment.rb

Essentially what I want to do is keep my email username and password in a separate file to my environment.rb I've used the initializers in other places to do this - but here the environment seems to be loaded first:
development.rb
config.action_mailer.smtp_settings = {
:address => "smtp.example.com",
:port => 587,
:domain => "www.example.com",
:authentication => "plain",
:user_name => SMTP_USERNAME,
:password => SMTP_PASSWORD,
:enable_starttls_auto => true
}
When I start my Rails server I get an error:
uncaught exception: uninitialized constant SMTP_USERNAME
Would this be a scoping issue of due to the fact that the constants in the Initializers are declared after the environment, and what can I do about it?
What if you try defining your constants in application.rb, inside class Application < Rails::Application? You might then access the constants by doing something like Application::SMTP_USERNAME. That's just a guess.

Resources