Rails 4 - 如何使用 delayed_job 发送类似时事通讯的电子邮件?
Rails 4 - How to send newsletter-like emails with delayed_job?
我想每天早上向我们的用户发送新列表的摘要。使用 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
但是,循环遍历数据库中的数百条记录并以延迟邮寄方法发送数百封电子邮件是否值得推荐(或适当)?
有更好的方法吗?
提前致谢!
为了简单起见,我通常更喜欢将 Sidekiq
与 Sidetiq
but if you want to use delayed_job
I would advice you to use the whenever
gem 一起使用。
Whenever is a Ruby gem that provides a clear syntax for writing and
deploying cron jobs.
- 将
gem 'whenever'
添加到您的 gem 文件
- 运行 命令
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
这样您将有一个延迟的工作来获取所有用户并使用单独的工作人员发送每封电子邮件,这是完成此任务的最佳方式。
Note: Do not forget to change the methods for listings in your view
from, for example, listing.title
to listing[:title]
since we are
passing the listings as json
.
If you do not want to pass them as json
every time to every delayed
task just cache the listings in Rails.cache
and clear it
after you finish sending.
编辑:
如果您想使用缓存方法,因为您 运行 在 delayed_job
gem 中遇到问题,请在您的邮件程序中编辑您的 send_daily_newsletter
方法。 (这就是为什么我会选择基于 redis 的 Sidekiq
而不是基于 mysql 的 delayed_job
。
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
祝你好运。我做这些电子邮件通讯已经有一段时间了,它们真的很痛苦:D
我想每天早上向我们的用户发送新列表的摘要。使用 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
但是,循环遍历数据库中的数百条记录并以延迟邮寄方法发送数百封电子邮件是否值得推荐(或适当)?
有更好的方法吗?
提前致谢!
为了简单起见,我通常更喜欢将 Sidekiq
与 Sidetiq
but if you want to use delayed_job
I would advice you to use the whenever
gem 一起使用。
Whenever is a Ruby gem that provides a clear syntax for writing and deploying cron jobs.
- 将
gem 'whenever'
添加到您的 gem 文件 - 运行 命令
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
这样您将有一个延迟的工作来获取所有用户并使用单独的工作人员发送每封电子邮件,这是完成此任务的最佳方式。
Note: Do not forget to change the methods for listings in your view from, for example,
listing.title
tolisting[:title]
since we are passing the listings asjson
.If you do not want to pass them as
json
every time to every delayed task just cache the listings inRails.cache
and clear it after you finish sending.
编辑:
如果您想使用缓存方法,因为您 运行 在 delayed_job
gem 中遇到问题,请在您的邮件程序中编辑您的 send_daily_newsletter
方法。 (这就是为什么我会选择基于 redis 的 Sidekiq
而不是基于 mysql 的 delayed_job
。
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
祝你好运。我做这些电子邮件通讯已经有一段时间了,它们真的很痛苦:D