【问题标题】:Sending email as a job on ruby on rails在 ruby​​ on rails 上发送电子邮件作为工作
【发布时间】:2019-06-08 03:07:09
【问题描述】:

大家好,

我创建了一个邮件程序来向我的客户发送电子邮件。截至目前,我仍在测试它,但我无法让它工作。我已经阅读了 redis、sidekiq、rails_mailer,但仍然一无所获。我可以看到邮件在 sidekiq UI 的队列中,但我收不到邮件。

这是我的代码流程。

  1. 如果用户想向客户发送电子邮件,他们将选中视图上的文本框。

  2. 我将在控制器上触发一个方法。这是我的代码。

      def send_workorder_message
        if params.has_key?(:to_send_email)
          WorkorderMessage::WorkorderMessageJob.perform_in(10.seconds, @curr_user, params[:message])
        end
      endv
  1. 然后创建工作单作业。这是代码。

class WorkorderMessage::WorkorderMessageJob
  # include SuckerPunch::Job
  include Sidekiq::Worker
  sidekiq_options queue: 'mailers'

  def perform(user, message)
    Spree::WorkorderMailer.workorder_send_to_email(user, message).deliver_now


    # ActiveRecord::Base.connection_pool.with_connection do

    # end

  end
end
  1. 之后会触发 WorkorderMailer 代码如下。
    class WorkorderMailer < BaseMailer
    def workorder_send_to_email(to_user, message)
      ActiveRecord::Base.connection_pool.with_connection do

        subject = "sample message mailer"

        @message = message
        @user = to_user

        mail(
          to: @user.email,
          # 'reply-to': Spree::Store.current.support_address,
          from: Spree::Store.current.support_address,
          subject: subject
        )
      end
    end
  end

当我使用预览邮件时,我可以看到 UI 工作正常。

我还注意到,在 sidekiq 视图中,我看到了这个 User Obj。我有那么正常吗?

【问题讨论】:

  • 我想知道您的ActionMailer::Base.smtp_settings 是否配置不正确,无法发送交易电子邮件。您可以分享您的ActionMailer::Base.smtp_settings 并省略任何敏感凭据吗?
  • 您正在指定作业转到mailers 队列。您是否使用 -q mailers 启动 Sidekiq 以便处理此队列?
  • 如有疑问,请不要配置任何东西。让它使用默认值,一切都会开箱即用。
  • MikePerham,MFrazier 你好,先生。实际上,我们有一个工作邮件。这只是工作中的补充。我的前辈正在度假,只有我和他。但如果我能得到代码库,我会在周一发送一些详细信息。谢谢

标签: ruby-on-rails ruby actionmailer jobs sidekiq


【解决方案1】:

根据the Sidekiq documentation,您传递的参数必须是干净地序列化为 JSON 的原语,而不是完整的 Ruby 对象,例如您在此处传递的 user

复杂的 Ruby 对象不会转换为 JSON,默认情况下它会 用 to_s 转换,看起来像 #&lt;Quote:0x0000000006e57288&gt;。即使 他们确实正确地序列化了,如果您的队列备份并且 报价对象同时发生变化?不要将状态保存到 Sidekiq,保存简单的标识符。查找对象后 实际上在您的执行方法中需要它们。 传递给 perform_async 的参数必须由简单的 JSON 数据类型:string、integer、float、boolean、null(nil)、array 和 哈希。这意味着您不能使用 ruby​​ 符号作为参数。这 Sidekiq 客户端 API 使用 JSON.dump 将数据发送到 Redis。这 Sidekiq 服务器从 Redis 中提取 JSON 数据并使用 JSON.load 将数据转换回 Ruby 类型以传递给您的 perform 方法。 不要传递符号、命名参数或复杂的 Ruby 对象(如 日期或时间!)因为那些将无法在转储/加载往返中存活 正确。

我建议您将其更改为在作业中按 ID 查找用户,并且只传递 ID 而不是整个用户对象。

# pass @curr_user.id instead of @curr_user
WorkorderMessage::WorkorderMessageJob.perform_in(10.seconds, @curr_user.id, params[:message])

# accept the ID instead of user here
def perform(user_id, message)

  # get the user object here
  user = User.find(user_id)

  # send the mail
  mail(
    to: user.email,
    #...
end

【讨论】:

  • 感谢您的回复先生。我听从了你的建议。仍然一无所获。我还在def performSpree::WorkorderMailer 上添加了一个断点,它只命中def perform 方法而不是方法的内容。这就是为什么我认为workorder_send_to_email 方法没有被调用。
  • 您可能无法让工作人员在断点处停止,因为它通常在另一个进程中工作。 puts "got here" 应该可以工作,如果你可以看到输出,或者你可以Rails.logger.info("got here"),然后查看你的日志文件。
  • 试过了,但没有显示日志。我还将deliver_later 更改为deliver_now 什么也没发生。奇怪的是它在我的 sidekiq 上显示,所以从技术上讲它正在处理这项工作,但我无法收到任何电子邮件。
猜你喜欢
  • 1970-01-01
  • 2013-06-08
  • 1970-01-01
  • 2015-08-25
  • 2015-06-15
  • 2016-10-09
  • 2020-03-15
  • 2012-08-29
  • 2012-08-14
相关资源
最近更新 更多