Ruby on rails 3 DelayedJob导致ActionMailer中的变量缓存到生产中?

Ruby on rails 3 DelayedJob导致ActionMailer中的变量缓存到生产中?,ruby-on-rails-3,caching,actionmailer,delayed-job,prawn,Ruby On Rails 3,Caching,Actionmailer,Delayed Job,Prawn,我们正在使用Amazon SES发送电子邮件,这就是为什么我们使用DelayedJob发送所有可能非常庞大的电子邮件。DelayedJob将这些要发送的电子邮件排成队列,其间至少间隔一秒钟 它通常工作得很好,但我发现在ActionMailer模板中缓存的变量以及与这些电子邮件一起发送的生成的PDF中存在问题。PDF是使用对虾生成的 比如说,我们所有的客户都有一个唯一的ID,我给两个客户发了一封电子邮件。第一个客户端具有ID1234,第二个客户端具有ID2345。发生的情况是,两个客户端都收到一封

我们正在使用Amazon SES发送电子邮件,这就是为什么我们使用DelayedJob发送所有可能非常庞大的电子邮件。DelayedJob将这些要发送的电子邮件排成队列,其间至少间隔一秒钟

它通常工作得很好,但我发现在ActionMailer模板中缓存的变量以及与这些电子邮件一起发送的生成的PDF中存在问题。PDF是使用对虾生成的

比如说,我们所有的客户都有一个唯一的ID,我给两个客户发了一封电子邮件。第一个客户端具有ID
1234
,第二个客户端具有ID
2345
。发生的情况是,两个客户端都收到一封ID为
1234
的电子邮件。不过,这两封电子邮件都会发送给正确的人,其他一些变量也会正确呈现

我最初认为这个问题与在我的电子邮件模板中使用助手有关。我将分享一个例子:

<%- @extra_lines.each do |line|
  if @interpolations
    @interpolations.each do |key,value|
      line = line.html_safe.sub "%{#{key}}", value.to_s
    end
  end %>
  <p><%= line.html_safe %></p>
<%- end %>
此邮件程序模板:

<%- @extra_lines.each do |line|
  if @interpolations
    @interpolations.each do |key,value|
      line = line.html_safe.sub "%{#{key}}", value.to_s
    end
  end %>
  <p><%= line.html_safe %></p>
<%- end %>

该控制器:

class RandomController < ApplicationController
  def index
    extra_lines = [
      'Test line 1',
      'Test line 2 with %{variable}',
      'Test line 3'
    ]
    10.times do
      interpolations = {variable: rand(1..100)}
      arguments = {extra_lines: extra_lines, interpolations: interpolations}
      MyMailer.delay.random_amount(arguments)
    end
    render :text => "Master, I've scheduled mail for you."
  end
end
class RandomController“主人,我已经为您安排了邮件。”
结束
结束
这是我能达到的最接近“真实”应用程序的结果,它会向我发送10封带有唯一随机数量的电子邮件。所以,基本上,我无法重现这个问题,更令人困惑的是,大多数时候它只是起作用


有没有人对此感到惊讶?

我想我已经找到了我问题的答案,而且比我原来想的要简单得多。额外的@行是从I18n阵列构建的。我这样做是因为这些文本在电子邮件、PDF和网页中使用,而且因为它们是多语言的,我想将这些文本存储在一个中心位置,我觉得I18n非常完美,但它不支持数组中的插值,这意味着我必须自己进行


因此,长话短说,在PDF类中,我循环遍历生成的数组并使用
line.sub进行插值!“{{key}}”,value.to_s
(与
line=line.sub(..)
)相反,它还更新
@extra_-lines
变量,该变量更新
I18n.t('get.specific.extra.lines')
查询的(缓存)结果。当它再次尝试插值这些字符串时,会对已插值(缓存)的字符串运行插值,因此不会发生插值。这就解释了为什么电子邮件在我的测试中工作得很好:如果我在发送电子邮件之前生成了PDF,它就会工作。

我在您的代码中注意到的第一件事是,在“mailer template”中,您正在为@Interpolation执行一个each循环,并将line设置为一个字符串。这意味着只有在循环的最后一次迭代中,vil才会出现在行变量中。。。这是故意的吗?你能详细说明一下吗?在每次迭代中,
变量通过用
替换任何匹配的
%{key}
来更新。
@interpolations
中的每个键都是唯一的。只有
=
每次迭代都会覆盖最后一次。因此,如果您想向line变量添加多个插值,您需要在
@插值之前将其删除。每个
循环,并在循环内使用
line+=..
。否则,line变量将只包含
@插值的上一次迭代的字符串。每个
可能我误解了您的意思,但是请注意
line
变量已经设置好了,我没有执行
line=somethingelse
,而是实际执行
line=line.sub(…)
。它在每一次
@插值中都被更新。每一次
循环。所以,最初它可以是
Hello这是%{var1}和%{var2}
,在第一个循环之后,它就像
Hello这是我和%{var2}
,用
%{var1}
替换
me
,在第二个循环之后它可以是
Hello这是我和你
。啊。对不起,我的错!读一下代码,快一点:)
class RandomController < ApplicationController
  def index
    extra_lines = [
      'Test line 1',
      'Test line 2 with %{variable}',
      'Test line 3'
    ]
    10.times do
      interpolations = {variable: rand(1..100)}
      arguments = {extra_lines: extra_lines, interpolations: interpolations}
      MyMailer.delay.random_amount(arguments)
    end
    render :text => "Master, I've scheduled mail for you."
  end
end