Rails 4 - 如何使用delayed_job发送类似时事通讯的电子邮件?

时间:2015-12-06 13:12:37

标签: ruby-on-rails ruby email 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

然而,循环浏览数据库中的数百条记录并以推迟(或适当)的延迟邮件方式发送数百封电子邮件?

有更好的方法吗?

提前谢谢!

1 个答案:

答案 0 :(得分:3)

我通常更喜欢使用SidekiqSidetiq,但如果您想使用delayed_job,我建议您使用whenever gem来简化。

  

每当Ruby gem提供清晰的写法和语法时   部署cron jobs。

  1. gem 'whenever'添加到您的gemfile
  2. 运行命令wheneverize .,生成文件config/schedule.rb
  3. config/schedule.rb执行以下操作。

    every 1.day, :at => '11:30 am' do
      runner "User.delay.send_daily_newsletter"
    end
    
  4. 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
    
  5. 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
    
  6. 通过这种方式,您将有一个延迟的工作来获取所有用户并使用单独的工作人员发送每封电子邮件,这是执行此任务的最佳方式。

      

    注意:不要忘记在视图中更改列表的方法   例如,从listing.titlelisting[: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