设计异步/延迟作业 - 发送延迟作业的自定义电子邮件?

时间:2011-11-22 22:48:54

标签: ruby-on-rails devise delayed-job

我有一个解决方案,我可以发送设计'股票电子邮件'默认包含在具有延迟作业的Devise中的邮件消息。以异步方式。因此,我使用以下代码:

/initializers/devise_acync.rb

module Devise


  module Models

    module Confirmable
      alias_method :send_confirmation_instructions_without_delay, :send_confirmation_instructions
      handle_asynchronously :send_confirmation_instructions
    end

    module Recoverable
      alias_method :send_reset_password_instructions_without_delay, :send_reset_password_instructions
      handle_asynchronously :send_reset_password_instructions
    end

    module Lockable
      alias_method :send_unlock_instructions_without_delay, :send_unlock_instructions
      handle_asynchronously :send_unlock_instructions
    end

    module Invitable
      alias_method :deliver_invitation_without_delay, :deliver_invitation
      handle_asynchronously :deliver_invitation
    end


  end

end

在我的用户模型设计链接到此模型我做

def confirm!
    welcome_message
    super
  end

private

  def welcome_message
     ::Devise.mailer.welcome_instructions(self).deliver
  end

让我眼花缭乱的重大问题: 我怎样才能发送此欢迎信息true delayed_job? 你会如何添加其他自定义的电子邮件,而不是设计包含这些电子邮件,以便他们发送真正的delayed_job?

6 个答案:

答案 0 :(得分:3)

我发现这是一个优雅的解决方案 - http://danseaver.com/blog/2011/10/18/sending-devise-emails-with-delayed-job

我稍微更改了它以处理所有传出的设计电子邮件,运行rails 3.0.7 + DJ 3.0.1

<强>配置/初始化/ devise.rb

# override Devise::Mailer to use queue outgoing mail into DJ
class DeviseMailer < Devise::Mailer

  def confirmation_instructions(record)
    Devise::Mailer.delay.confirmation_instructions(record)
  end

  def reset_password_instructions(record)
    Devise::Mailer.delay.reset_password_instructions(record)
  end

  def unlock_instructions(record)
   Devise::Mailer.delay.unlock_instructions(record)
  end
end

# Use this hook to configure devise mailer, warden hooks and so forth. The first
# four configuration values can also be set straight in your models.
Devise.setup do |config|
  # ==> Mailer Configuration
  # Configure the e-mail address which will be shown in DeviseMailer.
  config.mailer_sender = APP_CONFIG[:member_email]

  # Configure the class responsible to send e-mails.
  config.mailer = "DeviseMailer"
...

答案 1 :(得分:3)

最好使用devise-aync gem或结帐这个小blogpost

答案 2 :(得分:1)

我发现以上都不适合我。我正在使用Devise 2.0.4和Rails 3.2.2 with delayed_job_active_record 0.3.2

设计实际上谈论在代码中的注释中执行类似操作的方式是覆盖User类中的方法。因此,我这样解决了它,它完美地运作:

应用程序/模型/ User.rb

def send_on_create_confirmation_instructions
  Devise::Mailer.delay.confirmation_instructions(self)
end
def send_reset_password_instructions
  Devise::Mailer.delay.reset_password_instructions(self)
end
def send_unlock_instructions
  Devise::Mailer.delay.unlock_instructions(self)
end

答案 3 :(得分:0)

您是否尝试过这样做:

def welcome_message
  ::Devise.mailer.delay.welcome_instructions(self)
end

答案 4 :(得分:0)

通过覆盖User模型上的单个方法,这实际上很容易实现。 Devise通过send_devise_notification方法发送所有电子邮件,因此只需将其中的代码更改为异步友好。

def send_devise_notification(notification, opts = {})
  devise_mailer.delay.send(notification, self, opts)
end

此代码假设Sidekiq,但语法可能与Resque或DelayedJob兼容。

答案 5 :(得分:0)

(问题已接近3岁,但仍然很容易通过谷歌找到,所以这是我的贡献)

最佳做法是按照来源https://github.com/plataformatec/devise/blob/master/lib/devise/models/authenticatable.rb#L129

中描述的设备说明进行操作
class User
  devise :database_authenticatable, :confirmable

  after_commit :send_pending_notifications

  protected

  def send_devise_notification(notification, *args)
    # If the record is new or changed then delay the
    # delivery until the after_commit callback otherwise
    # send now because after_commit will not be called.
    if new_record? || changed?
      pending_notifications << [notification, args]
    else
      devise_mailer.send(notification, self, *args).deliver
    end
  end

  def send_pending_notifications
    pending_notifications.each do |notification, args|
      devise_mailer.send(notification, self, *args).deliver
    end

    # Empty the pending notifications array because the
    # after_commit hook can be called multiple times which
    # could cause multiple emails to be sent.
    pending_notifications.clear
  end

  def pending_notifications
    @pending_notifications ||= []
  end
end

您只需要替换2次出现的

devise_mailer.send(notification, self, *args).deliver

通过

devise_mailer.delay.send(notification, self, *args)