Resque и Resque_mailer с Devise

Я реализую фоновую обработку электронной почты с помощью Resque, используя гем resque_mailer (https://github.com/zapnap/resque_mailer). Мне удалось заставить его работать со всеми моими электронными письмами, кроме тех, которые были отправлены Devise.

Я просмотрел кучу SO-вопросов и сообщений в блогах (например, http://teeparham.posterous.com/send-devise-emails-with-resque), но не смог найти способ заставить его работать.

Каковы точные шаги, чтобы заставить resque_mailer работать с Devise?


person alex    schedule 11.01.2013    source источник
comment
возможный дубликат отправки электронных писем Devise через Resque   -  person James McMahon    schedule 21.11.2013


Ответы (2)


Я бы посмотрел на devise-async. Похоже, это соответствует вашему варианту использования. Разработка асинхронного режима

person Adam    schedule 11.01.2013
comment
Просто любопытно: при каких обстоятельствах я буду использовать собственный класс почтовой программы (Devise::Async.mailer = MyCustomMailer)? - person alex; 12.01.2013
comment
Внезапно я бы подумал, что вы должны создать пользовательскую почтовую программу, если вам нужно переопределить одно из существующих действий почтовой программы, confirm_instructions, reset_password_instructions или unlock_instructions, чтобы включить больше данных в представление электронной почты. - person Adam; 12.01.2013

Я просмотрел ответ 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
comment
это решение все еще работает для вас или вам пришлось внести какие-либо изменения? Я спрашиваю, потому что я боролся с этим в течение нескольких дней. Я чувствую, что это решение приближает меня к devise, resque и resque_mailer, но оно все еще вызывает проблемы. Любопытно, пробовали ли вы resque_mailer activerecordserializer? - person jonbcampos; 11.05.2016
comment
Наша текущая кодовая база все еще в основном такая же, и мы отправляем письма о разработке через resque_mailer. С какой ошибкой/проблемой вы столкнулись? Я изменил (обновил выше) наш метод send_devise_notification, чтобы учесть глобальную конфигурацию, но существующий код в ответе должен работать. Протестировано с devise 3.5.6 и resque_mailer 2.2.7 - person mintuhouse; 13.05.2016