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.)


Jawaban:


324

Di kelas mailer yang Anda gunakan untuk mengelola email Anda:

class ReportMailer < ActionMailer::Base
  add_template_helper(AnnotationsHelper)

  ...
end

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)


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

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.)


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


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: 'user@domain.com',
    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 .. .


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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.