我想每天早上向用户发送新列表的摘要。使用Ruby On Rails 4,ActiveRecord(使用SendGrid)和延迟作业的最佳方法是什么?
我目前正在这样做:
在控制器中:
def yesterday_listings_for_users
yesterday_listings = Listings.where('status = "0" AND (DATE(created_at) = ?)', Date.today - 1)
if yesterday_listings.count > 0
NotificationMailer.delay.yesterday_listings_for_users_notification
end
render :nothing => true
end
然后在邮件中:
def yesterday_listings_for_users_notification
@listings = Listing.where('status = "0" AND (DATE(created_at) = ?)', Date.today-1)
mail(to: 'myemail@gmail.com', subject: "Latest Listings", from: 'no-reply@mywebsite.com')
end
使用CRON作业时,我每天早上都会通过电子邮件地址向我发送报告。我在数据库中有几百个用户,我也想发送这封电子邮件。
怎么做?我想知道这样的事情:
def yesterday_listings_for_users_notification
@listings = Listing.where('status = "0" AND (DATE(created_at) = ?)', Date.today-1)
Users.all.each do |user|
mail(to: user.email, subject: "Latest Listings", from: 'no-reply@mywebsite.com')
end
end
然而,循环浏览数据库中的数百条记录并以推迟(或适当)的延迟邮件方式发送数百封电子邮件?
有更好的方法吗?
提前谢谢!
答案 0 :(得分:3)
我通常更喜欢使用Sidekiq
和Sidetiq
,但如果您想使用delayed_job
,我建议您使用whenever
gem来简化。
每当Ruby gem提供清晰的写法和语法时 部署cron jobs。
gem 'whenever'
添加到您的gemfile wheneverize .
,生成文件config/schedule.rb
在config/schedule.rb
执行以下操作。
every 1.day, :at => '11:30 am' do
runner "User.delay.send_daily_newsletter"
end
在user.rb
中定义方法send_daily_newsletter
并使用find_each
代替all.each
(批次)
def self.send_daily_newsletter
listings = Listing.where('status = "0" AND (DATE(created_at) = ?)', Date.today - 1).select(:title).to_json
User.select(:id, :email).find_each do |u|
NotificationMailer.delay.send_daily_newsletter(u.email, listings)
end
end
在notification_mailer.rb
定义send_daily_newletter
def send_daily_newsletter(user_email, listings)
@listings = listings
mail(to: user_email, subject: "Latest Listings", from: 'no-reply@mywebsite.com')
end
通过这种方式,您将有一个延迟的工作来获取所有用户并使用单独的工作人员发送每封电子邮件,这是执行此任务的最佳方式。
注意:不要忘记在视图中更改列表的方法 例如,从
listing.title
到listing[:title]
,因为我们是 将列表作为json
传递。如果您不希望每次延迟都将
json
传递给delayed_job
任务只是缓存Rails.cache
中的列表并清除它 完成发送后。
修改强>
如果您想在send_daily_newsletter
gem遇到问题时使用缓存方法,请在邮件程序中修改Sidekiq
方法。 (那就是为什么我会去基于redis的delayed_job
而不是基于mysql的 def send_daily_newsletter(user_email)
@listings = Rails.cache.fetch('today_listings') { Listing.where('status = "0" AND (DATE(created_at) = ?)', Date.today - 1) }
mail(to: user_email, subject: "Latest Listings", from: 'no-reply@mywebsite.com')
end
。
user.rb
并在 def self.send_daily_newsletter
User.select(:id, :email).find_each do |u|
NotificationMailer.delay.send_daily_newsletter(u.email)
end
Rails.cache.clear('today_listings')
end
return "Your profits are " + str(profit1) + " " + str(profit2) + " " + str(profit3) + " "
祝你好运。我一直在做这些电子邮件通讯一段时间,他们真的很痛苦:D