Как использовать мои помощники в моих представлениях ActionMailer?

227

Я хочу использовать методы, которые я определил app/helpers/annotations_helper.rbв моих представлениях ReportMailer ( app/views/report_mailer/usage_report.text.html.erb). Как мне это сделать?

Основываясь на этом руководстве, кажется, что add_template_helper(helper_module)метод может делать то, что я хочу, но я не могу понять, как его использовать.

(Кстати, есть ли причина, по которой вы получаете доступ к другому набору помощников в представлениях почтовой программы? Это довольно раздражает.)

Том Леман
источник
подобный - amolnpujari.wordpress.com/2013/12/27/…
Амол Пуджари

Ответы:

324

В классе почтовой программы, который вы используете для управления своей электронной почтой:

class ReportMailer < ActionMailer::Base
  add_template_helper(AnnotationsHelper)

  ...
end
Марк Коннелл
источник
4
В этом случае у меня не работает (Rails 3.2.8): у меня есть метод, определенный в ApplicationController, и я делаю его вспомогательным с помощью helper_method: my_helper_wannabe, но метод "my_helper_wannabe" не доступен в почтовой программе.
Гианг Нгуен
Смотрите ответ Дьюка ниже, чтобы узнать, как работать с Rails 3.
Крис Питерс
Работает в Rails 3.2.11
Jan
1
Я думал, что они должны были быть автоматически включены в Rails 4? guides.rubyonrails.org/…
gabeodess
6
Это древний ответ, но я просто хочу сказать, что это сработало в Rails 5.2
Archonic
158

В Rails 3 просто используйте вспомогательный метод в верхней части вашего класса ActionMailer:

helper :mail   # loads app/helpers/mail_helper.rb & includes MailHelper

Я только что прошел в блоке, так как мне нужно только в одном Mailer:

helper do
  def host_url_for(url_path)
    root_url.chop + url_path
  end
end

(не забудьте установить config.action_mailer.default_url_options.)

(и если вы используете url_for, обязательно укажите: only_path => false)

герцог
источник
3
Это работает, но приятно переопределять помощников, уже определенных в ApplicationController, для отдельных классов ActionMailer. ActionMailer расширяет ActionController, поэтому они происходят из общей иерархии. Больше комментариев о Rails, чем ваше решение ...
robbie613
3
И если помощник находится в пространстве имен, вы можете это сделатьhelper :'namespace/mail'
Джонатон Бэтсон
если помощник находится в пространстве имен, он также принимает только строку (вместо символа)helper 'namespace/mail'
Pwnrar
2
Работает на Rails 5.2!
РуссоАлександр
28

Для всех почтовых программ в Rails 3 (настройка помощника application):

# config/application.rb:
...
config.to_prepare do
  ActionMailer::Base.helper "application"
end
Эдисон Мачадо
источник
Лучший ответ для общих почтовых неполадок. Спасибо!
Алексей Шеин
2
НЕ верно - helper :applicationотлично работает в Rails 4.2.1.
стейкчезер
Хорошо работает даже для собственных шаблонов электронной почты devise. helper :applicationне работает в этом случае.
Свен Р.
1
не работает на 4.2.5.1 - include ApplicationHelperработает
daslicious
23

Для Ruby on Rails 4 мне пришлось сделать 2 вещи:

(1) Как уже сказал герцог , если помощник, которого вы хотите добавить, это, UsersHelperнапример, добавить

helper :users

к производному ActionMailerклассу (например,app/mailers/user_mailer.rb )

(2) После этого я получил новую ошибку:

ActionView::Template::Error (Missing host to link to! Please provide the :host
parameter, set default_url_options[:host], or set :only_path to true)

Чтобы это исправить, добавьте строку

config.action_mailer.default_url_options = { :host => 'localhost' }

к каждому из config/environments/*.rbфайлов. Для config/environments/production.rb, замените localhostего более подходящим хостом для URL-адресов, сгенерированных вспомогательным рабочим


В: Для # 2, почему почтовому представлению нужна эта информация, а обычным - нет?

A: Поскольку обычные представления не должны знать host, так как все сгенерированные ссылки обслуживаются с хоста, на который они ссылаются. Ссылки, отображаемые в электронных письмах, не обслуживаются с одного хоста (если вы не ссылаетесь на hotmail.comили gmail.comи т. Д.)

Matt
источник
Как насчет сочиненных имен? User::ComposedHelper
Кирилл Дюшон-Дорис
20

Вы можете просто добавить в свой почтовик

helper :application

или какой-нибудь помощник вам нужен

user1136228
источник
4
это дубликат предыдущего ответа - @Shevaun
robbie613
1
Работает на Rails 5.2!
РуссоАлександр
17

(Это старый вопрос, но Rails эволюционировал, поэтому я делюсь тем, что работает для меня в Rails 5.2.)

Как правило, вы можете использовать пользовательский помощник представления при отображении строки темы электронного письма, а также HTML. В случае, когда помощник вида находится в app / helpers / application_helper.rb следующим образом:

module ApplicationHelper

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

end

Я могу создать динамическую строку темы письма и шаблон, которые оба используют помощника, но мне нужно указать Rails явно использовать ApplicationHelper в apps / mailer / user_mailer.rb двумя различными способами, как вы можете видеть во второй и третьей строках здесь :

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

Я должен отметить, что эти две строки работают одинаково хорошо, поэтому выберите одну или другую:

helper :application

add_template_helper(ApplicationHelper)

FWIW, шаблон электронной почты в app / views / user_mailer / party_thanks.html.erb выглядит так:

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

И контроллер app / controller / party_controller.rb выглядит следующим образом

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

Я должен согласиться с OP (@Tom Lehman) и @gabeodess, что все это выглядит довольно запутанным, учитывая https://guides.rubyonrails.org/action_mailer_basics.html#using-action-mailer-helpers, так что, возможно, я что-то упустил .. ,

MSC
источник
5

в моем случае для Rails4 я делаю так:

# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  add_template_helper ApplicationHelper
  ...
end

и

# app/mailers/user_mailer.rb
class AccountMailer < ApplicationMailer
  def some_method(x, y)
  end
end

так что вам не нужно указывать add_template_helperвезде.

Йоши
источник