Bagaimana cara menggunakan view helper saya dalam tampilan ActionMailer?

227

Saya ingin menggunakan metode yang saya tetapkan dalam app/helpers/annotations_helper.rbtampilan ReportMailer saya ( app/views/report_mailer/usage_report.text.html.erb). Bagaimana saya melakukan ini?

Berdasarkan panduan ini, sepertinya add_template_helper(helper_module)metode ini dapat melakukan apa yang saya inginkan, tetapi saya tidak tahu cara menggunakannya.

(BTW, apakah ada alasan Anda mendapatkan akses ke perangkat pembantu yang berbeda dalam tampilan mailer? Ini sangat menjengkelkan.)

Tom Lehman
sumber
yang serupa - amolnpujari.wordpress.com/2013/12/27/…
Amol Pujari

Jawaban:

324

Di kelas mailer yang Anda gunakan untuk mengelola email Anda:

class ReportMailer < ActionMailer::Base
  add_template_helper(AnnotationsHelper)

  ...
end
Mark Connell
sumber
4
Tidak berfungsi untuk saya dalam kasus ini (Rails 3.2.8): Saya memiliki metode yang didefinisikan dalam ApplicationController dan menjadikannya penolong oleh helper_method: my_helper_wannabe, tetapi metode "my_helper_wannabe" tidak tersedia di mailer.
Giang Nguyen
Lihat jawaban Duke di bawah ini untuk cara menangani di Rails 3.
Chris Peters
Bekerja di Rel 3.2.11
Jan
1
Saya pikir ini seharusnya secara otomatis dimasukkan dalam Rails 4? guide.rubyonrails.org/…
gabeodess
6
Ini adalah jawaban kuno tetapi hanya berdentang untuk mengatakan ini bekerja di Rails 5.2
Archonic
158

Di Rails 3, cukup gunakan metode helper di bagian atas kelas ActionMailer Anda:

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

Saya baru saja melewati satu blok, karena saya hanya membutuhkannya di satu Mailer:

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

(pastikan untuk mengatur config.action_mailer.default_url_options.)

(dan jika Anda menggunakan url_for, pastikan untuk memasukkan: only_path => false)

Bangsawan tinggi
sumber
3
Ini berfungsi, tetapi rasanya ingin menentukan kembali pembantu yang telah didefinisikan di ApplicationController ke kelas ActionMailer individual juga. ActionMailer memperluas ActionController sehingga mereka berasal dari hierarki umum. Lebih banyak komentar di Rails daripada solusi Anda ...
robbie613
3
Dan jika helper ada di namespace yang bisa Anda lakukanhelper :'namespace/mail'
Jonathon Batson
jika helper ada di namespace, ia juga hanya menerima string (bukan simbol)helper 'namespace/mail'
Pwnrar
2
Bekerja pada Rails 5.2!
RousseauAlexandre
28

Untuk semua pengirim di Rails 3 (mengatur pembantu "aplikasi"):

# config/application.rb:
...
config.to_prepare do
  ActionMailer::Base.helper "application"
end
Edison Machado
sumber
Jawaban terbaik untuk sebagian email yang dibagikan. Terima kasih!
Alexey Shein
2
TIDAK benar - helper :applicationberfungsi dengan baik di Rails 4.2.1.
steakchaser
Bekerja dengan baik bahkan untuk templat email sendiri devise. helper :applicationtidak berfungsi dalam kasus ini.
Sven R.
1
tidak bekerja untuk 4.2.5.1 - include ApplicationHelperberhasil
daslicious
23

Untuk Ruby on Rails 4, saya harus melakukan 2 hal:

(1) Seperti yang sudah dikatakan Duke , jika helper yang ingin Anda tambahkan adalah UsersHelpercontoh, maka tambahkan

helper :users

ke ActionMailerkelas turunan (mis. app/mailers/user_mailer.rb)

(2) Setelah itu, saya mendapat kesalahan baru:

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

Untuk memperbaikinya, tambahkan baris

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

ke masing-masing config/environments/*.rbfile. Untuk config/environments/production.rb, ganti localhostdengan host yang lebih sesuai untuk url yang dihasilkan helper produksi.


T: Untuk # 2, mengapa tampilan email memerlukan informasi ini, dan tampilan biasa tidak?

A: Karena tampilan biasa tidak perlu diketahui host, karena semua tautan yang dihasilkan disajikan dari host yang mereka tautkan. Tautan yang muncul dalam email tidak dilayani dari host yang sama (kecuali jika Anda menautkan ke hotmail.comatau gmail.com, dll.)

Mat
sumber
Bagaimana dengan nama yang dikomposisikan? User::ComposedHelper
Cyril Duchon-Doris
20

Anda bisa menambahkan di mailer Anda

helper :application

atau pembantu apa pun yang Anda butuhkan

pengguna1136228
sumber
4
ini merupakan duplikat dari respons sebelumnya - @Shevaun
robbie613
1
Bekerja pada Rails 5.2!
RousseauAlexandre
17

(Ini adalah pertanyaan lama tetapi Rails telah berevolusi jadi saya berbagi apa yang cocok untuk saya di Rails 5.2.)

Biasanya Anda mungkin ingin menggunakan penolong tampilan khusus dalam merender baris subjek email dan juga HTML. Dalam kasus di mana view helper ada di app / helpers / application_helper.rb sebagai berikut:

module ApplicationHelper

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

end

Saya dapat membuat baris subjek dan templat email dinamis yang sama-sama menggunakan helper, tetapi saya harus memberi tahu Rails untuk menggunakan ApplicationHelper secara eksplisit di apps / mailer / user_mailer.rb dengan dua cara berbeda, seperti yang Anda lihat di baris kedua dan ketiga di sini :

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: '[email protected]',
    subject: "Thanks for coming on #{mydate(@party.created_at, @party.timezone)}")
  end

end

Saya harus menyebutkan bahwa kedua baris ini bekerja dengan baik jadi pilih satu atau yang lain:

helper :application

add_template_helper(ApplicationHelper)

FWIW, templat email di app / views / user_mailer / party_thanks.html.erb terlihat seperti ini:

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

Dan pengontrol app / controller / party_controller.rb terlihat seperti ini

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

Saya harus setuju dengan OP (@ Tom Lehman) dan @ gabeodess bahwa ini semua terasa cukup berbelit-belit karena https://guides.rubyonrails.org/action_mailer_basics.html#using-action-mail-mailer-helpers jadi mungkin saya kehilangan sesuatu .. .

MSC
sumber
5

dalam kasus saya untuk Rails4, saya suka ini:

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

dan

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

sehingga Anda tidak perlu menentukan di add_template_helpermana-mana.

Yoshi
sumber