我正在使用delayed_job,我对它非常满意(特别是workless扩展名)。
但我想设置我的应用中的所有邮件是异步发送的。
确实,为邮寄者提供的解决方案
# without delayed_job
Notifier.signup(@user).deliver
# with delayed_job
Notifier.delay.signup(@user)
不适合我,因为:
我可以使用这种扩展程序https://github.com/mhfs/devise-async,但我宁愿一次找出整个应用程序的解决方案。
我无法扩展ActionMailer
以覆盖.deliver
方法(例如此处https://stackoverflow.com/a/4316543/1620081,但它已有4年历史,就像我在该主题上发现的几乎所有文档一样)?
我正在使用带有activerecord的Ruby 1.9和Rails 3.2。
感谢您的支持
答案 0 :(得分:0)
一个简单的解决方案是在Notifier对象上编写实用程序方法,如下所示:
class Notifier
def self.deliver(message_type, *args)
self.delay.send(message_type, *args)
end
end
按如下方式发送注册电子邮件:
Notifier.deliver(:signup, @user)
实用程序方法提供了一个单点,如果需要,您可以使用resque或sidekiq解决方案替换延迟作业。
答案 1 :(得分:0)
如果您已设置ActiveJob并且并发库已完成设置documentation here。最简单的解决方案是覆盖与交易邮件相关的设备 send_devise_notification 实例方法,例如{{ 3}}
class User < ApplicationRecord
# whatever association you have here
devise :database_authenticatable, :confirmable
after_commit :send_pending_devise_notifications
# whatever methods you have here
protected
def send_devise_notification(notification, *args)
if new_record? || changed?
pending_devise_notifications << [notification, args]
else
render_and_send_devise_message(notification, *args)
end
end
private
def send_pending_devise_notifications
pending_devise_notifications.each do |notification, args|
render_and_send_devise_message(notification, *args)
end
pending_devise_notifications.clear
end
def pending_devise_notifications
@pending_devise_notifications ||= []
end
def render_and_send_devise_message(notification, *args)
message = devise_mailer.send(notification, self, *args)
# Deliver later with Active Job's `deliver_later`
if message.respond_to?(:deliver_later)
message.deliver_later
# Remove once we move to Rails 4.2+ only, as `deliver` is deprecated.
elsif message.respond_to?(:deliver_now)
message.deliver_now
else
message.deliver
end
end
end