在Rails 5.1.3中为继承的ActionMailer对象设置deliver_later_queue_name

ros*_*der 1 ruby ruby-on-rails ruby-on-rails-5

我正在尝试在 Rails 5.1.3 应用程序中为事务邮件处理和批量邮件处理设置单独的邮件程序队列。根据 (配置选项),我应该能够通过设置deliver_later_queue_name.

我有以下课程:

class ApplicationMailer < ActionMailer::Base
end

class UserMailer < ApplicationMailer  self.deliver_later_queue_name = 'mail'
  self.deliver_later_queue_name = 'mail'
  self.smtp_settings = {
    address: "smtp.sendgrid.net",
    port: 587,
    ...
}

class BulkMailer < ApplicationMailer
  self.deliver_later_queue_name = 'bulkmail'
  self.smtp_settings = {
    address: "email-smtp.us-west-2.amazonaws.com",
    port: 587,
    ...
  }
Run Code Online (Sandbox Code Playgroud)

这对于 smtp_settings 来说效果很好,但是它deliver_later_queue_name似乎是一个类变量?因此,当我在BulkMailer或中设置它时UserMailer,它会更改所有 ActionMailer 的设置。

deliver_later_queue_name有谁知道我可以为 BulkMailer 和 UserMailer设置单独的方法吗?

bcd*_*bcd 5

deliver_later_queue_name定义为cattr_accessor(参见此处)。从文档cattr_accessor您可以看到:

如果子类更改了该值,那么父类的值也会更改。类似地,如果父类更改了值,那么子类的值也会更改。

因此,没有一种简单的方法可以使用deliver_later_queue_name.

一种选择是在入队时设置队列:

BulkMailer.offer(offer, user).deliver_later(queue: :bulkemail)
Run Code Online (Sandbox Code Playgroud)

另一种选择是,如果您想通过使用它来运行 Rails Edge,ActionMailer::Base.delivery_job那么class_attribute您可以在子类中覆盖它(文档在这里)。

实施将是:

class RegularEmailsJob < ActionMailer::DeliveryJob
  queue_as :mail
end
class BulkEmailsJob < ActionMailer::DeliveryJob
  queue_as :bulkmail
end

class UserMailer < ApplicationMailer
  self.deliver_job = RegularEmailsJob
  # ...
end

class BulkMailer < ApplicationMailer
  self.deliver_job = BulkEmailsJob
  # ...
end
Run Code Online (Sandbox Code Playgroud)

另一个类似的选择是您不依赖deliver_later并拥有自己的工作来发送电子邮件deliver_now

class EmailsDeliveryJob
  def perform(mailer_class, mailer_method, *args)
    mailer_class.send(mailer_method, *args)
  end
end
class RegularEmailsJob < EmailsDeliveryJob
  queue_as :mail
end
class BulkEmailsJob < EmailsDeliveryJob
  queue_as :bulkmail
end

# and when you want to send an email you do
RegularEmailsJob(UserMailer, :welcome, @user)

# At this point you can get creative in making your syntax better (a helper)
Run Code Online (Sandbox Code Playgroud)