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