Làm cách nào để sử dụng trình trợ giúp chế độ xem của tôi trong chế độ xem ActionMailer của tôi?


227

Tôi muốn sử dụng các phương thức mà tôi đã xác định trong các app/helpers/annotations_helper.rbchế độ xem Báo cáo ( app/views/report_mailer/usage_report.text.html.erb) của tôi. Làm thế nào để tôi làm điều này?

Dựa trên hướng dẫn này, có vẻ như add_template_helper(helper_module)phương pháp có thể làm những gì tôi muốn, nhưng tôi không thể tìm ra cách sử dụng nó.

(BTW, có lý do gì bạn có quyền truy cập vào một nhóm người trợ giúp khác trong chế độ xem của người gửi thư không? Điều này khá khó chịu.)


Câu trả lời:


324

Trong lớp người gửi thư mà bạn đang sử dụng để quản lý email của mình:

class ReportMailer < ActionMailer::Base
  add_template_helper(AnnotationsHelper)

  ...
end

4
Không hoạt động với tôi trong trường hợp này (Rails 3.2.8): Tôi có một phương thức được xác định trong ApplicationContoder và làm cho nó trở thành một trình trợ giúp bởi helper_method: my_helper_wannabe, nhưng phương thức "my_helper_wannabe" không khả dụng trong trình gửi thư.
Giang Nguyễn

Xem câu trả lời của Duke bên dưới để biết cách xử lý trong Rails 3.
Chris Peters

Hoạt động trong Rails 3.2.11
Jan

1
Tôi nghĩ những thứ này được cho là sẽ tự động được đưa vào Rails 4? guide.rubyonrails.org/ Từ
gabeodess

6
Đây là một câu trả lời cổ xưa nhưng chỉ cần nói để làm việc này trong Rails 5.2
Archonic

158

Trong Rails 3, chỉ cần sử dụng phương thức của trình trợ giúp ở đầu lớp ActionMailer của bạn:

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

Tôi vừa vượt qua trong một khối, vì tôi chỉ cần nó trong một Mailer:

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

(hãy chắc chắn đặt config.action_mailer.default_url_options.)

(và nếu bạn sử dụng url_for, hãy chắc chắn chuyển vào: only_path => false)


3
Điều này hoạt động, nhưng cảm thấy bất lợi khi chỉ định lại các trình trợ giúp đã được xác định trong ApplicationContoder cho các lớp ActionMailer riêng lẻ. ActionMailer mở rộng ActionContoder để chúng đến từ một hệ thống phân cấp chung. Nhiều nhận xét về Rails hơn là giải pháp của bạn ...
robbie613

3
Và nếu người trợ giúp ở trong một không gian tên bạn có thể làmhelper :'namespace/mail'
Jonathon Batson

nếu người trợ giúp ở trong một không gian tên thì nó cũng chỉ chấp nhận một chuỗi (thay vì ký hiệu)helper 'namespace/mail'
Pwnrar

2
Hoạt động trên Rails 5.2!
RousseauAlexandre

28

Đối với tất cả các thư trong Rails 3 (cài đặt trình trợ giúp "ứng dụng"):

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

Câu trả lời tốt nhất cho các email chia sẻ. Cảm ơn!
Alexey Shein

2
KHÔNG đúng - helper :applicationhoạt động tốt trong Rails 4.2.1.
bít tết

Hoạt động tốt ngay cả đối với các mẫu email riêng cho devise. helper :applicationkhông hoạt động trong trường hợp này.
Sven R.

1
không làm việc cho 4.2.5.1 - include ApplicationHelperđã làm việc
daslicious

23

Đối với Ruby on Rails 4, tôi phải làm 2 việc:

(1) Như Duke đã nói, nếu người trợ giúp bạn muốn thêm UsersHelperchẳng hạn, thì hãy thêm

helper :users

đến ActionMailerlớp dẫn xuất (ví dụ app/mailers/user_mailer.rb)

(2) Sau đó, tôi gặp một lỗi mới:

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

Để khắc phục điều này, hãy thêm dòng

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

đến từng config/environments/*.rbtệp. Đối với config/environments/production.rb, thay thế localhostbằng một máy chủ thích hợp hơn cho các url được tạo bởi người trợ giúp sản xuất.


Q: Đối với # 2, tại sao chế độ xem thư cần thông tin này và các chế độ xem thông thường thì không?

Trả lời: Bởi vì các chế độ xem thông thường không cần biết host, vì tất cả các liên kết được tạo đều được phục vụ từ máy chủ mà chúng liên kết đến. Liên kết hiển thị trong email không được phục vụ từ cùng một máy chủ (trừ khi bạn đang liên kết đến hotmail.comhoặc gmail.com, v.v.)


Tên sáng tác thì sao? User::ComposedHelper
Cyril Duchon-Doris

20

Bạn chỉ có thể thêm vào mailer của bạn

helper :application

hoặc bất cứ người trợ giúp nào bạn cần


4
đây là bản sao của phản hồi trước đó - @Shevaun
robbie613

1
Hoạt động trên Rails 5.2!
RousseauAlexandre

17

(Đây là một câu hỏi cũ nhưng Rails đã phát triển nên tôi chia sẻ những gì phù hợp với tôi trong Rails 5.2.)

Thông thường, bạn có thể muốn sử dụng trình trợ giúp chế độ xem tùy chỉnh để hiển thị dòng chủ đề của email cũng như HTML. Trong trường hợp người trợ giúp xem app / helpers / application_helper.rb như sau:

module ApplicationHelper

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

end

Tôi có thể tạo một dòng tiêu đề và mẫu tiêu đề email động mà cả hai đều sử dụng trình trợ giúp nhưng tôi cần nói với Rails để sử dụng ApplicationHelper một cách rõ ràng trong apps / mailer / user_mailer.rb theo hai cách khác nhau, như bạn có thể thấy trong dòng thứ hai và thứ ba ở đây :

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

Tôi nên đề cập rằng hai dòng này cũng hoạt động tốt vì vậy hãy chọn một hoặc hai dòng khác:

helper :application

add_template_helper(ApplicationHelper)

FWIW, mẫu email tại app / Views / user_mailer / party_thanks.html.erb trông như thế này:

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

ứng dụng / bộ điều khiển / party_controll.rb trông như thế này

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

Tôi phải đồng ý với OP (@Tom Lehman) và @gabeodess rằng tất cả điều này cảm thấy khá khó chịu khi được đưa ra https://guides.rubyonrails.org/action_mailer_basics.html#USE-action-mailer-helpers vì vậy có lẽ tôi đang thiếu thứ gì đó .. .


5

trong trường hợp của tôi cho Rails4, tôi làm như thế này:

# 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

để bạn không phải chỉ định add_template_helperở mọi nơi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.