我希望在约会开始前一小时触发邮件。我正在使用@appointment
实例变量中的at字段。
class AppointmentController < ApplicationController
def create
if DateTime.now + 1.hour > @appointment.at
AppointmentReminder.send_appointment_email(@appointment).deliver_now
end
end
end
如果约会是在一小时内创建的,但是如果约会是在将来创建的......那么我们的不良客户就不会得到通知。是否存在Rails可以在合适的时间自动发送电子邮件的机制?我不想使用cronjob或rake任务。
答案 0 :(得分:1)
我建议您查看Sidekiq或Sucker Punch等后台处理系统,这些系统可配置为“稍后”执行作业。
这样,在创建约会时,您可以安排作业在正确的时间执行。您需要添加检查以确保作业最终运行时仍然合法,等等。
答案 1 :(得分:0)
当您将问题标记为与rails 4.2相关时,然后Active Job正是您需要的。
答案 2 :(得分:0)
您可以使用whenever按计划运行代码块。比如说,只需5分钟,就会查找在下一个小时内开始的约会并发送电子邮件。
为防止多台服务器发送电子邮件,您可以在约会上获得状态,以便跟踪电子邮件是否已发送。
然后,使用postgres,您可以使用此SQL来获取要发送的记录,并使用数据库来决定将哪个服务器发送出特定的电子邮件:
Email.find_by_sql("WITH updated AS (
UPDATE emails SET status = 'processing' where lower(status) = 'new' RETURNING id
)
SELECT *
FROM emails
WHERE id IN (SELECT id FROM updated)
order by id asc
&#34)
答案 3 :(得分:0)
我将分享我的工作方式。效果很好。
首先,每当gem都安装一次。
您应该有您的邮件。这是我的:
class WeeklyDigestMailer < ApplicationMailer
default :from => "bla@bla.org"
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.weekly_digest_mailer.weekly_promos.subject
#
helper ApplicationHelper
def weekly_promos(suscriptor, promos)
@promos = promos
mail(:to => "<#{suscriptor.email}>", :subject => "Mercadillo digital semanal")
end
end
当然,您需要设置视图样式。
然后,创建一个rake任务(在lib / tasks中)。就是这样:
desc 'send digest email'
task send_weekly_email: :environment do
@promociones = Promo.where("validez > ?", Time.zone.now).order("created_at DESC")
if (@promociones.count > 0)
@suscriptors = Suscriptor.where(email_confirmation: true)
@suscriptors.each do |suscriptor|
WeeklyDigestMailer.weekly_promos(suscriptor, @promociones).deliver_now
end
end
end
最后,您可以使用gem来配置时间表。我想在整个星期四上午9点发送邮件,所以我只说了:
every :thursday, at: '9:00 am' do # Use any day of the week or :weekend, :weekday
rake "send_weekly_email"
end
重要的一点:由于您正在使用rake任务,因此请使用delivery_now而不是delivery_later,因为如果任务在所有电子邮件发送之前完成,其余部分将无法发送。
仅此而已。