因为没有实例化邮件服务API密钥,所以我收到了一些未发送的电子邮件。但是, Detail 模型对象保留在数据库中。我不想在数据库中重新创建这些。
我编写了一个rake任务来发送电子邮件,并且更容易尝试创建一些临时的内存中对象,而不是尝试根据detail_params中的内容找到正确的ActiveRecord对象。然后我使用 DetailMailerJob 发送电子邮件,并传入实例化的 Detail 对象。
temp_obj = Detail.new(detail_params)
DetailMailerJob.new.delay.notify_job(temp_obj)
但是我在运行rake任务后注意到Delayed :: Job.all队列中的以下错误:
last_error: "ActiveRecord::RecordNotFound
这是否意味着我将 Detail 对象传入 DetailMailerJob 的唯一方法是首先在数据库中找到实例化的记录? (即没有内存中的对象)
编辑:这是DetailMailer& DetailMailerJob类。
class DetailMailerJob
def notify_job(detail)
DetailMailer.notify_job(detail).deliver
end
end
class DetailMailer < ActionMailer::Base
def notify_job(detail)
@detail = detail
@emailed_to = detail.emailed_to.join(", ")
mail(to: detail.emailed_to, subject: "#{detail.full_name} - New Message")
end
end
答案 0 :(得分:1)
我也遇到过这种情况。使用已保存的ActiveRecord::Base
子类版本而不是在DJ队列中再次保留完整内容是DJ的优化。我确信他们这样做是因为AR的实例可能很大。
如果您定义的新类与[{1}}感兴趣的字段相同,但不继承自Detail
,.类似的东西:
ActiveRecord::Base
现在用一个实例启动作业:
class DetailAsAPlainOldRubyObject
attr_accessor :field_a, :field_b, ...
def initialize(params)
self.field_a = params['field_a']
self.field_b = params['field_b']
...
end
end
更多详细信息:延迟作业 - 特别是方法temp_obj = DetailAsAPlainOldRubyObject.new(detail_params)
DetailMailerJob.new.delay.notify_job(temp_obj)
- 通过存储delay
类(在您的示例中为self
),名称来起作用方法(DetailMailerJob
)的方法,以及数据库表中参数的序列化表示。 Worker处理从表中出列记录,反序列化参数,并在类上调用该方法。
问题在于序列化。 DJ使用仅编码表名和主键的特殊serializer for ActiveRecord来增加YAML。反序列化表中notify_job
的结果。我想他们这样做是为了节省数据库空间和时间。当然,这个技巧只有在find
被保存的情况下才有效。 (如果DJ没有保存记录,如果DJ跳过了棘手的序列化,那将是很酷的,但唉它没有。)
在上面链接的代码中注意您的错误消息!它在ActiveRecord
失败时引发的异常中使用。
通过使用没有find
基础的普通对象,您应该将正常的YAML序列化为字符串。