Я просмотрел ответ tee и несколько ресурсов в Интернете, но не смог найти рабочий раствор.
После нескольких дней чтения кода resque-mailer и разработки решение, которое сработало для меня. Спасибо за суть, которая направила меня в правильном направлении.
Предполагая, что ваш app/mailers/application_mailer.rb
похож на
class ApplicationMailer < ActionMailer::Base
include Resque::Mailer # This will add a `self.perform` class method, which we will overwrite in DeviseResqueMailer
end
In config/initializers/devise.rb
Devise.parent_mailer = "ApplicationMailer"
Devise.setup do |config|
config.mailer = 'DeviseResqueMailer'
end
В классе ресурсов, который использует devise, перезапишите метод send_devise_notification
для отправки класса ресурсов и идентификатора вместо объекта, чтобы предотвратить сортировку.
# app/models/user.rb
protected
def send_devise_notification(notification, *args)
# Based on https://github.com/zapnap/resque_mailer/blob/64d2be9687e320de4295c1bd1b645f42bd547743/lib/resque_mailer.rb#L81
# Mailer may completely skip Resque::Mailer in certain cases - and will fail as we write custom handle in DeviseResqueMailer assuming mails are handled via resque
# So in those cases, don't retain original devise_mailer so things work properly
if ActionMailer::Base.perform_deliveries && Resque::Mailer.excluded_environments.exclude?(Rails.env.to_sym)
# Originally devise_mailer.send(notification, self, *args).deliver
# Modified to ensure devise mails are safely sent via resque
resource_id, resource_class = self.id, self.class.name
devise_mailer.send(notification, {resource_id: resource_id, resource_class: resource_class}, *args).deliver
else
super
end
end
Наконец, в app/mailers/devise_resque_mailer.rb
снова извлеките запись из базы данных и продолжите
class DeviseResqueMailer < Devise::Mailer
def self.perform(action, *args)
# Hack to prevent RuntimeError - Could not find a valid mapping for admin.attributes
record_hash = args.shift
record = record_hash["resource_class"].constantize.find(record_hash["resource_id"])
args.unshift(record)
super # From resque-mailer
end
end
Я считаю, что этот подход лучше, чем использование devise-async, поскольку все письма проходят через один и тот же путь кода. Его легче контролировать и перезаписывать при необходимости.
person
mintuhouse
schedule
14.10.2015