我有一个像这样的邮件程序
class Mailer < ActionMailer::Base
def newsletter_scheduler()
recipients = User.all.to_a
Mailer.delay_for(certain_time.days).newsletter(recipients)
end
def newsletter(recipients)
recipients.each do |user|
Logger.log("sending newsletter to #{user.email}"
mail(
to: user.email,
subject: "What's hot last week",
).deliver
end
end
我不是在寻找替代方案来实现这个......
问题是,这只是将简报发送给最后一个收件人而且是多次
例如,在specs
it 'sends newsletter to all users' do
Mailer.newsletter_scheduler()
newsletters = ActionMailer::Base.deliveries
newsletters.each { |nl| p nl.to }
end
我明白了(注意:我有5个用户)
["josh@haley.org"]
["josh@haley.org"]
["josh@haley.org"]
["josh@haley.org"]
["josh@haley.org"]
任何人都可以告诉我为什么在记录器显示以下内容时发生这种情况
sending newsletter to gertrude@gleasonlittle.biz
sending newsletter to bell@cormier.org
sending newsletter to alexa_sanford@rosenbaum.name
sending newsletter to hillard@mcclure.org
sending newsletter to josh@haley.org
[编辑] 以下代码与上面的代码具有相同的效果
class Newsletter
def self.schedule
recipients = User.all.map { |u| u.id }
Mailer.delay_for(certain_time.days).newsletter(recipients)
end
end
class Mailer < ActionMailer::Base
def newsletter(recipients)
recipients.each do |id|
user = User.find(id)
Logger.log("sending newsletter to #{user.email}"
mail(
to: user.email,
subject: "What's hot last week",
)
end
end
Newsletter.schedule() #produces the same results in the specs
答案 0 :(得分:2)
您的代码也提出了另一个问题。我在上面的代码中向您展示了邮件操作之外的#deliver
。
考虑拆分代码
class NewsletterScheduler
def self.execute
User.all.each do |user|
Mailer.delay_for(certain_time.days).newsletter(user)
end
end
end
class Mailer < ActionMailer::Base
def newsletter(user)
Logger.log("sending newsletter to #{user.email}"
mail(to: user.email, subject: "What's hot last week")
end
end
NewsletterScheduler.execute
重要警告:您绝不应将复杂对象作为参数传递给队列。相反,始终传递参考。
在你的情况下改变
def newsletter(recipients)
接受一组ID而不是User对象数组。原因是对象很复杂,内部状态可能会发生变化,特别是如果它们存储在数据库中。此外,序列化原始值比序列化复杂对象更有效。
class NewsletterScheduler
def self.execute
User.all.each do |user|
Mailer.delay_for(certain_time.days).newsletter(user_id)
end
end
end
class Mailer < ActionMailer::Base
def newsletter(user_id)
user = User.find(user_id)
Logger.log("sending newsletter to #{user.email}"
mail(to: user.email, subject: "What's hot last week")
end
end