Last night I was preparing a weekly email to remind my dear TimeSampler users about the work they have done in their previous week.
I started by adding a couple of previews one for the user that has actual stuff done (see an example below):

Setup a mailer (you can skip this)
The first thing you need to preview an email is to have a Mailer (yuk!), here’s a simple one:
# app/mailers/user_notifier
class UserNotifier < ActionMailer::Base
default from: 'weekly-report@timesampler.com', reply_to: 'elia+timesampler-weekly-report@schito.me'
helper DayHelper
def weekly_report user
@user = user
@project_days = project_days
@days = project_days.group_by(&:day).to_a.sort
@end_time = end_time
@start_time = start_time
mail to: user.email, subject: "TimeSampler: Weekly activity report · week #{start_time.cweek}"
end
end
And its view:
/ app/views/user_notifier
= render 'style'
%h1 TimeSampler: Weekly activity report · week #{@start_time.cweek}
%p
Hi #{@user.some_name}!
- if @project_days.any?
%p
Here's what you've done during the past week (#{link_to "from #{@start_time} to #{@end_time}", journal_path}):
.days
- @days.sort.reverse.each do |(day, project_days)|
= render 'day', day: day, project_days: project_days
- else
= render 'blank_slate'
= render 'footer'
Setup a previewer
Then we need to add our previewer. Problem is that the default location for the previewers is test/mailers/previews
and as you may have guessed already we have no test
dir in this app, instead we’ll put our
ActionMailer::Preview
classes inside app/mailer_previews
.
To do that let’s add the following line to config/environments/development
:
Rails.application.configure do
# …
config.action_mailer.preview_path = "#{Rails.root}/app/mailer_previews"
end
Your previewer could be something like this:
class UserNotifierPreview < ActionMailer::Preview
def weekly_report_empty
UserNotifier.weekly_report(andrea)
end
def weekly_report_full
UserNotifier.weekly_report(elia)
end
# …s
end
And have beautyful previews for your emails. For example, this is how the blankslate TimeSampler mail looks like:

POWER PREVIEWING !!1!
Now what if you want to preview emails for arbitrary users without having to manually update the code?
No problem, luckly it’s Ruby! After a bit of inspection inside actionmailer and railties I found the right hook…

Rails asks the previewer if an email_exists?
before trying to display it, so we’ll hook into that method and
auto-define a previewer instance method for each user in out system (please don’t try this with more than a hundred users).
Here teh codez:
class UserNotifierPreview < ActionMailer::Preview
def self.email_exists?(*)
User.all.each do |user|
next if user.email.blank?
email = user.email.gsub(/W/, '_')
method_name = "weekly_report_#{email}"
user_id = user.id
define_method method_name do
UserNotifier.weekly_report(User.find(user_id))
end
end
super
end
# …
end
Of course it’s advisable to be careful and probably reduce the set of users you’re gonna prepare a preview method for.
In my case the development database is quite manageable and hence User.all
is fine.
Final Pro-tip
You find cumbersome to dig the sources of the gems in your bundle even
if you setup the $EDITOR
var in your bash and are a regular client of bundle open <my-gem>
?
Then you can give a try to the Bundler bundle for TextMate2 which will give you an
incredible speed boost while perusing the gems in your current Gemfile.lock
.
To get some more info on my TextMate2 setup you can read:
