在 Ruby on Rails 上将发送电子邮件作为一项工作

问题描述 投票:0回答:1

我创建了一个邮件程序来向我的客户发送电子邮件。截至目前,我仍在测试它,但我无法使其工作。我读过 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。这正常吗?

ruby-on-rails ruby actionmailer jobs sidekiq
1个回答
1
投票

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

user

复杂的 Ruby 对象不会转换为 JSON,默认情况下它会 使用 to_s 进行转换,看起来像

#<Quote:0x0000000006e57288>
。即使 他们确实序列化正确,如果你的队列备份并且 那个报价对象同时发生变化?不要将状态保存到 Sidekiq,保存简单的标识符。查找对象后 实际上在您的执行方法中需要它们。 传递给perform_async的参数必须由简单的 JSON 数据类型: string、integer、float、boolean、null(nil)、array 和 哈希。这意味着您不能使用 ruby 符号作为参数。这 Sidekiq 客户端 API 使用 JSON.dump 将数据发送到 Redis。这 Sidekiq 服务器从 Redis 中提取 JSON 数据并使用 JSON.load 来 将数据转换回 Ruby 类型以传递给您的执行方法。 不要传递符号、命名参数或复杂的 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
© www.soinside.com 2019 - 2024. All rights reserved.