How to use my view helpers in my ActionMailer views?

Viewed 66335

I want to use the methods I defined in app/helpers/annotations_helper.rb in my ReportMailer views (app/views/report_mailer/usage_report.text.html.erb). How do I do this?

Based on this guide it seems like the add_template_helper(helper_module) method might do what I want, but I can't figure out how to use it.

(BTW, is there a reason you get access to a different set of helpers in mailer views? This is pretty annoying.)

8 Answers

(This is an old question but Rails has evolved so I'm sharing what works for me in Rails 5.2.)

Typically you might want to use a custom view helper in rendering the subject line of an email as well as the HTML. In the case where the view helper is in app/helpers/application_helper.rb as follows:

module ApplicationHelper

  def mydate(time, timezone)
    time.in_time_zone(timezone).strftime("%A %-d %B %Y")
  end

end

I can create a dynamic email subject line and template which both use the helper but I need to tell Rails to use the ApplicationHelper explicitly in apps/mailer/user_mailer.rb in two different ways, as you can see in the second and third lines here:

class UserMailer < ApplicationMailer

  include ApplicationHelper  # This enables me to use mydate in the subject line
  helper :application  # This enables me to use mydate in the email template (party_thanks.html.erb)

  def party_thanks
    @party = params[:party]
    mail(to: 'user@domain.com',
    subject: "Thanks for coming on #{mydate(@party.created_at, @party.timezone)}")
  end

end

I should mention that these two lines work just as well so choose one or the other:

helper :application

add_template_helper(ApplicationHelper)

FWIW, the email template at app/views/user_mailer/party_thanks.html.erb looks like this:

<p>
  Thanks for coming on <%= mydate(@party.created_at, @party.timezone) %>
</p>

And the app/controller/party_controller.rb controller looks like this

class PartyController < ApplicationController
  ...
  def create
    ...
    UserMailer.with(party: @party).party_thanks.deliver_later
    ...
  end
end

I have to agree with OP (@Tom Lehman) and @gabeodess that this all feels quite convoluted given https://guides.rubyonrails.org/action_mailer_basics.html#using-action-mailer-helpers so perhaps I am missing something...

This is what I did in rails 6

class ApplicationMailer < ActionMailer::Base
  default from: 'community@example.com'
  layout 'mailer'

  # Add whatever helper you want
  helper :application  

end
Related