【问题标题】:Set deliver_later_queue_name for inherited ActionMailer object in Rails 5.1.3在 Rails 5.1.3 中为继承的 ActionMailer 对象设置 Deliver_later_queue_name
【发布时间】:2017-08-26 05:00:44
【问题描述】:

我正在尝试在我的 Rails 5.1.3 应用程序中为事务邮件处理和批量邮件处理设置单独的邮件队列。根据this (配置选项),我应该可以通过设置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,
    ...
  }

这适用于 smtp_settings,但 deliver_later_queue_name 似乎是一个类变量?所以当我在BulkMailerUserMailer 中设置它时,它会为所有ActionMailer 更改它。

有没有人知道我为 BulkMailer 和 UserMailer 设置单独的 deliver_later_queue_name 的方法?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-5


    【解决方案1】:

    deliver_later_queue_namecattr_accessor 定义(参见here)。从cattr_accessordocumentation可以看出:

    如果子类更改了值,那么这也会更改父类的值。同样,如果父类改变了值,那么子类的值也会改变。

    因此,使用deliver_later_queue_name 可以做到这一点并不容易。

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

    BulkMailer.offer(offer, user).deliver_later(queue: :bulkemail)
    

    另一个选项是,如果您想使用 ActionMailer::Base.delivery_job 来运行 rails edge,这是用 class_attribute 定义的,因此您可以在子类中覆盖它(文档 here)。

    实现是:

    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
    

    另一个类似的选择是您不要依赖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)
    

    【讨论】:

    • 哇,感谢您提供非常清晰、内容丰富的答案!
    • 我无法在 Rails 5.2.3 中重现相同的情况
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 2013-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 2012-01-05
    相关资源
    最近更新 更多