##Refs
- RailsGuides: ActionMailer Basics
- Railscast: ActionMailer in Rails 3
- Railscast: Sending HTML Email
- Gem: Mail_View preview email without sending
- Gist: Setting Up SettingsLogic Gem
- Blog: How to test mailers in Rails 3 with RSpec
In terminal:
rails g mailer UserMailer
or create a mailers/user_mailer.rb
class UserMailer < ActionMailer::Base
layout 'mailer_default'
def user_email(user)
@user = user
@url = "http://example.com/login"
mail(
charset: "utf-8",
content_type: "text/html",
from: Settings.mailer.from,
subject: "Email Test",
to: user.email
)
end
end
create a layout for emails as views/layouts/mailer_default.html.haml
!!!
%html{ lang: "en" }
%head
%body
#wrapper
=yield
create a partial for the email header at views/shared/_mailer_header_default.html.haml
#header{ style: "color: blue;" }
%p
This is header content
create a partial for the email footer at views/shared/_mailer_footer_default.html.haml
#footer{ style: "color: red;" }
%p
This is footer content
create a view for emails as views/user_mailer/user_email.html.haml
= render :partial => "shared/mailer_header_default"
#content{ style: "color: green;" }
%p
This is the content of the User Email
= render :partial => "shared/mailer_footer_default"
Add to file config/settings.yml
mailer:
from: "FirstName LastName <[email protected]>"
address: "smtp.gmail.com"
port: 587
domain: "gmail.com"
user_name: <%= ENV["MAILER_USERNAME"] %>
password: <%= ENV["MAILER_PASSWORD"] %>
authentication: "plain"
enable_starttls_auto: true
create a file name config/intializers/mailer_settings.rb
ActionMailer::Base.smtp_settings = {
address: Settings.mailer.address,
port: Settings.mailer.port,
domain: Settings.mailer.domain,
user_name: Settings.mailer.user_name,
password: Settings.mailer.password,
authentication: Settings.mailer.authentication,
enable_starttls_auto: Settings.mailer.enable_starttls_auto
}
On heroku:
$ heroku config:add MAILER_USERNAME=gmail.com --remote stage
$ heroku config:add MAILER_PASSWORD=password --remote stage
On local:
$ export MAILER_USERNAME=gmail.com --remote stage
$ export MAILER_PASSWORD=password --remote stage
Fire off an email using this line of ruby:
UserMailer.user_email(@user).deliver
Add to your Gemfile (:test and :dev) with specific Github
commit to prevent breaking
group :test, :development do
gem 'mail_view', git: 'git://github.com/37signals/mail_view.git', ref: '6a4bc7f01a'
end
In Terminal run bundle install
Add lines to the Mailer models
class UserMailer < ActionMailer::Base
layout 'mailer_default'
def user_email(user)
@user = user
mail(
charset: "utf-8",
content_type: "text/html",
from: Settings.mailer.from,
subject: "User Email Test",
to: user.email
)
end
#add this code
class Preview < MailView
def user_email
user = User.first
mail = UserMailer.user_email(user)
mail
end
end
end
Add new routes to config/routes.rb
if Rails.env.development?
mount UserMailer::Preview => 'preview_email'
end
Go to http://example.com/preview_email
to review
Check that this line is un-commented in config/environments/test.rb
config.action_mailer.delivery_method = :test
Add to app/models/user.rb
def send_user_email(user)
UserMailer.user_email(user).deliver
end
require 'spec_helper'
describe User do
describe 'mailers' do
it "sends a user_email" do
user = FactoryGirl.create(:user, email: "[email protected]", password: "secret")
user.send_user_email(user)
ActionMailer::Base.deliveries.last.to.should == [user.email]
end
end
end
create a file named spec/mailers/user_mailer_spec.rb
require "spec_helper"
describe UserMailer do
describe 'user_email' do
let(:user) { FactoryGirl.create(:user, email: "[email protected]", password: "secret") }
let(:mail) { UserMailer.user_email(user) }
#ensure that the subject is correct
it 'renders the subject' do
mail.subject.should == 'User Email Test'
end
#ensure that the receiver is correct
it 'renders the receiver email' do
mail.to.should == [user.email]
end
#ensure that the sender is correct
it 'renders the sender email' do
mail.from.should == ["[email protected]"]
end
#ensure that the @name variable appears in the email body
it 'assigns @name' do
mail.body.encoded.should match(user.name)
end
#ensure that the @confirmation_url variable appears in the email body
it 'assigns @confirmation_url' do
mail.body.encoded.should match("http://application_url/#{user.id}/confirmation")
end
end
end
Is
<%= yield %>
all that's required inmailer_default.html.erb
?