我们正在使用Amazon SES发送电子邮件,这就是为什么我们使用DelayedJob发送所有可能发送的电子邮件。 DelayedJob将这些电子邮件排队,并在它们之间至少间隔一秒发送。
它通常可以正常工作,但我发现变量的问题似乎缓存在ActionMailer模板中以及与这些电子邮件一起发送的生成的PDF中。 PDF是使用Prawn生成的。
比如说,我们所有的客户都有一个唯一的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
是一个变量,它包含一些基于一组条件生成的电子邮件的额外段落。 value
的每个成员的@interpolations
包含第二封电子邮件中的重复内容。在上述案例中,@interpolations
看起来像{user_id: 1234}
。
现在,并非所有变量都有此问题。如果我只是渲染一个从Mailer类中传递的变量,那么这不会发生。这就是为什么我担心我正在使用的其中一种辅助方法的输出被缓存。更是因为类似的行为发生在我的PDF类中。
因此我尝试通过生成启用了DelayedJob的新Rails应用程序并创建此邮件来重现此问题:
class MyMailer < ActionMailer::Base
default from: "from@example.com"
def random_amount(arguments)
@extra_lines = arguments[:extra_lines]
@interpolations = arguments[:interpolations]
mail to: 'to@example.com'
end
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
这就像我可以接近&#34;真实&#34;应用程序,它会发送10封电子邮件,其中包含独特的随机数量。所以,基本上,我无法重现问题,更令人困惑的是,大部分时间它都能正常工作。
有没有人在那里敲响任何铃声?
答案 0 :(得分:1)
我想我找到了问题的答案,这比我原先想象的要简单得多。 @extra_lines
是从I18n阵列构建的。我这样做是因为这些文本用于电子邮件,PDF和网页,因为它们是多语言的,我想将这些文本存储在一个中心位置,我觉得I18n是完美的,但它不是支持数组插值,这意味着我必须自己滚动。
所以,长话短说,在PDF类中,我循环遍历生成的数组并使用line.sub! "%{#{key}}", value.to_s
(而不是line = line.sub(..)
)进行插值,这也会更新@extra_lines
变量,它更新I18n.t('get.specific.extra.lines')
查询的(缓存)结果。当它再次尝试插入这些字符串时,它会对已插入的(缓存的)字符串运行插值,因此不会发生插值。这解释了为什么电子邮件在我的测试中工作正常:如果我在发送电子邮件之前生成了PDF,它就可以工作。