ฉันจะใช้ตัวช่วยเหลือมุมมองในมุมมอง ActionMailer ได้อย่างไร


227

ฉันต้องการใช้วิธีที่ฉันกำหนดไว้ในapp/helpers/annotations_helper.rbมุมมอง ReportMailer ของฉัน ( app/views/report_mailer/usage_report.text.html.erb) ฉันจะทำสิ่งนี้ได้อย่างไร

จากคู่มือนี้ดูเหมือนว่าadd_template_helper(helper_module)วิธีการอาจทำสิ่งที่ฉันต้องการ แต่ฉันไม่สามารถหาวิธีใช้งานได้

(BTW มีเหตุผลที่คุณเข้าถึงกลุ่มผู้ช่วยเหลือที่แตกต่างกันในมุมมองจดหมายหรือไม่นี่เป็นเรื่องที่ค่อนข้างน่ารำคาญ)


หนึ่งที่คล้ายกัน - amolnpujari.wordpress.com/2013/12/12/27
Amol Pujari

คำตอบ:


324

ในคลาสจดหมายที่คุณใช้เพื่อจัดการอีเมลของคุณ:

class ReportMailer < ActionMailer::Base
  add_template_helper(AnnotationsHelper)

  ...
end

4
ไม่ทำงานสำหรับฉันในกรณีนี้ (Rails 3.2.8): ฉันมีวิธีการที่กำหนดไว้ใน ApplicationController และทำให้มันเป็นตัวช่วยโดย helper_method: my_helper_wannabe แต่วิธีการ "my_helper_wannabe" ไม่มีให้ในจดหมาย
Giang Nguyen

ดูคำตอบของ Duke ด้านล่างสำหรับวิธีจัดการใน Rails 3
Chris Peters

ทำงานใน Rails 3.2.11
Jan

1
ฉันคิดว่าสิ่งเหล่านี้ควรจะรวมอยู่ใน Rails 4 โดยอัตโนมัติ? guide.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'
Jonathon Batson

ถ้าผู้ช่วยเหลืออยู่ใน namespace มันยังยอมรับเพียงสตริง (แทนสัญลักษณ์ a)helper 'namespace/mail'
Pwnrar

2
ใช้งานได้กับ Rails 5.2!
RousseauAlexandre

28

สำหรับเมลทั้งหมดใน Rails 3 (การตั้งค่าตัวช่วย "application"):

# config/application.rb:
...
config.to_prepare do
  ActionMailer::Base.helper "application"
end

คำตอบที่ดีที่สุดสำหรับชิ้นส่วนอีเมลที่แชร์ ขอบคุณ!
Alexey Shein

2
ไม่เป็นความจริง - helper :applicationทำงานได้ดีใน Rails 4.2.1
steakchaser

deviseทำงานได้ดีแม้สำหรับแม่แบบอีเมลตัวเอง helper :applicationไม่ทำงานในกรณีนี้
สเวนอาร์

1
ไม่ทำงาน 4.2.5.1 - include ApplicationHelperทำงานได้
daslicious

23

สำหรับ Ruby on Rails ฉันต้องทำ 2 สิ่ง:

(1) ดังที่Dukeได้กล่าวไว้หากผู้ช่วยที่คุณต้องการเพิ่มนั้นเป็น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 เหตุใดมุมมองเมลต้องการข้อมูลนี้และมุมมองปกติไม่

ตอบ: เนื่องจากมุมมองปกติไม่จำเป็นต้องทราบhostเนื่องจากลิงก์ที่สร้างขึ้นทั้งหมดให้บริการจากโฮสต์ที่ลิงก์เชื่อมโยงไปถึง ลิงก์ที่แสดงในอีเมลจะไม่ได้รับจากโฮสต์เดียวกัน (เว้นแต่คุณจะเชื่อมโยงไปยังhotmail.comหรือgmail.comอื่น ๆ )


ชื่อที่แต่งแล้วล่ะ? User::ComposedHelper
Cyril Duchon-Doris

20

คุณสามารถเพิ่มในจดหมายของคุณ

helper :application

หรือผู้ช่วยอะไรก็ตามที่คุณต้องการ


4
นี่เป็นคำซ้ำก่อนหน้านี้ - @Shevaun
robbie613

1
ใช้งานได้กับ Rails 5.2!
RousseauAlexandre

17

(นี่เป็นคำถามเก่า แต่ Rails ได้รับการพัฒนาดังนั้นฉันจึงแบ่งปันสิ่งที่ใช้ได้กับฉันใน Rails 5.2)

โดยทั่วไปแล้วคุณอาจต้องการใช้ตัวช่วยมุมมองที่กำหนดเองในการแสดงบรรทัดหัวเรื่องของอีเมลเช่นเดียวกับ HTML ในกรณีที่มุมมองผู้ช่วยเหลืออยู่ในแอพ / ผู้ช่วยเหลือ / application_helper.rbดังนี้:

module ApplicationHelper

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

end

ฉันสามารถสร้างหัวเรื่องหัวเรื่องอีเมลและเทมเพลตแบบไดนามิกซึ่งทั้งคู่ใช้ตัวช่วย แต่ฉันต้องบอก Rails ให้ใช้ ApplicationHelper อย่างชัดเจนในแอพ / 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>

และแอพ / คอนโทรลเลอร์ / 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ดังนั้นบางทีฉันไม่มีอะไร .. .


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ทุกที่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.