56

I have trying to access helper methods from a rails 3 mailer in order to access the current user for the session.

I put the helper :application in my mailer class, which seems to work, except the methods defined therein are not available to my mailer (i get undefined errors). Does anyone know how this is supposed to work?

Here's my class:

class CommentMailer < ActionMailer::Base
  default :from => "Andre Fournier <[email protected]>"

  helper :application
end

Thanks, Sean

8
  • Can you also include your code and method definition for getting the current user? Commented Feb 8, 2011 at 19:10
  • Sure, here it is (the reference in the mailer): :from => "#{current_sender.name} <#{current_sender.email}>" and the definition: def current_sender current_user end Commented Feb 8, 2011 at 19:15
  • I mean, do you have current_user defined in a helper method or in your application controller and if so, what's the definition? Commented Feb 8, 2011 at 19:19
  • In this app current_user is a helper method provided by Devise. However, when I call current_sender, which I defined in my application_helper file, I get an undefined error. The issue is not with current_user because it is never called. Commented Feb 8, 2011 at 19:53
  • My suggestion would be to add an alias to current_user from current_sender in your CommentMailer class instead of including the entire helper. If that doesn't work you'll need to make current_user available to your CommentMailer class. It's better to do this since it doesn't require including an entire helper module. Commented Feb 8, 2011 at 19:56

11 Answers 11

72

To enable you to access application helpers from the ActionMailer views, try adding this:

add_template_helper(ApplicationHelper)

To your ActionMailer (just under your default :from line).

3
  • 1
    Works! @Sean O'Hara - Y U don't accept this answer?
    – Greg
    Commented Nov 5, 2014 at 22:25
  • I had to include ::ApplicationHelper before add_template_helper(ApplicationHelper). Commented Jan 14, 2015 at 17:48
  • 3
    For rails 4+ you can also do helper ApplicationHelper Commented Jul 3, 2017 at 9:00
65

Use helper ApplicationHelper

class NotificationsMailer < ActionMailer::Base

  default from: "Community Point <[email protected]>"
  helper ApplicationHelper
  helper NotificationMailerHelper

  # ...other code...

NOTE: These helper methods are only available to the Views. They are not available in the mailer class (NotificationMailer in my example).

If you need them in the actual mailer class, use include ApplicationHelper, like so:

class NotificationMailer < ActionMailer::Base

  include ApplicationHelper

  # ... the rest of your mailer class.

end

From this other SO question.

1
  • 13
    It's important to know that these helper methods are not available in the mailer class (NotificationMailer in my example), but only to the views themselves. If you need them in the mailer class itself, you should be able to use include ApplicationHelper instead. Commented Aug 5, 2015 at 20:40
26

This is a very old question, but I don't see the full answer, so I will try as I didn't find another resource.

It depends on what you are doing with the methods that have been defined in the helper module. If they are class methods, and everything that's not called on a specific instance seem to be a class methods for 3.2.13, you need to use

extend ApplicationHelper

if an instance methods

include ApplicationHelper

and if you want to use them in a mailer view

helper ApplicationHelper
1
  • Thank you for this !!! I have no way of marking this as an answer. - Are the extend / include / helper depreciable , ie using extend covers include and helper ? Commented Dec 18, 2017 at 14:42
7

You could try mixing in the required helper module:

class CommentMailer < ActionMailer::Base
  include ApplicationHelper
end
1
  • 2
    I'm not sure if this will work from the views. I'm guessing no. But it will definitely work if you want to use the helpers in the mailer class itself.
    – aNoble
    Commented May 9, 2013 at 15:28
4

Josh Pinter's answer is correct, but I discovered that it is not necessary.

What is necessary is to name the helper correctly.

NotificationMailerHelper is correct. NotificationMailersHelper (note the s) is not correct.

The class and filename of the helper must match and be correctly spelled.

Rails 3.2.2

3

include ActionView::Helpers::TextHelper worked for me in the Mailer controller (.rb file). This allowed me to use the pluralize helper in a Mailer controller action (helpers worked fine from the get go in Mailer views). None of the other answers worked, at least not on Rails 4.2

1
  • Worked for me in Rails 5. Commented Jun 19, 2017 at 19:58
2

If you want to call helper method from ActionMailer you need to include helper (module) in Mailer file as, if Helper module name is “UserHelper”, then need to write following in Mailer file

class CommentMailer < ActionMailer::Base
    default :from => "Andre Fournier <[email protected]>"
    add_template_helper(UserHelper)
end

Or

class CommentMailer < ActionMailer::Base
    default :from => "Andre Fournier <[email protected]>"
    include UserHelper
end

Hope this is helpful.

2

The single method version of promoting a method to being a helper that is available in ApplicationController also works in ActionMailer:

class ApplicationMailer < ActionMailer::Base
  helper_method :marketing_host

  def marketing_host
    "marketing.yoursite.com"
  end
end

from there you can call marketing_host from any of your mailer views

1
  • This is the simplest way in Rails 5. Commented Feb 1, 2018 at 22:59
0

I'm not sure exactly what you are doing here, but when I want to access current_user from a mailer, I make a mailer method that I pass the user to as an argument:

class CommentMailer < ActionMailer::Base
  default :from => "Andre Fournier <[email protected]>"

  def blog_comment(user)
    @recipients                   = user.email
    @from                         = "[email protected]"
    @sent_on                      = Time.now
    @timestamp                    = Time.now
    @user                         = user
  end
end

With the above, @user, as well as all the other instance variables, are accessible from inside the mailer views ./views/comment_mailer/blog_comment.html.erb and ./views/comment_mailer/blog_comment.text.erb

Separately, you can make a helper called

comment_mailer_helper.rb

and put into that helper any methods that you want to be available to your mailer's views. This seems to me more like what you might want, regarding helpers, because helpers are designed to help views, whereas a mailer is analogous to a controller.

0

None of the *_path helpers are accessible by default inside of an email. It is necessary instead to use the *_url form of the wanted helper. So, for instance, instead of using user_path(@user) it is necessary to use user_url(@user). See at Action Mailer basics.

-4

A hackish means of achieving what I wanted is to store the objects I need (current_user.name + current_user.email) in thread attributes, like so: Thread.current[:name] = current_user.name. Then in my mailer I just assigned new instance variables to those values stored in the thread: @name = Thread.current[:name]. This works, but it won't work if using something like delayed job.

Not the answer you're looking for? Browse other questions tagged or ask your own question.