Thursday, March 22, 2012

Update DelayedJob run_at to change daily emails send time

Below is just a sample code.
1) Create a table to track delayed jobs

class CreateTrackDelayedJobs < ActiveRecord::Migration
  def self.up
    create_table :track_delayed_jobs do |t|
      t.integer :delayed_job_id
      t.integer :user_id
      t.integer :item_id

      t.timestamps
    end
  end

  def self.down
    drop_table :track_delayed_jobs
  end
end




2)Sample code to send daily news letters

a) Add a rake task which can be run everyday

task :send_news_letters => :environment do
        items = Item.all
        items.each do |current_item|
          
            send_time = Time.zone.local(Date.today.year, Date.today.month, Date.today.day, hours, minutes)
            NewsLetter.send_at(send_time, :send_digest, curent_item.id)
        end

b)

class NewsLetter

 def self.send_in(time, method, *args)
        send_at time.from_now, method, *args
    end

    def self.send_at(time, method, *args)
        dj = Delayed::Job.enqueue Delayed::PerformableMethod.new(self, method.to_sym, args), 0, time
        track_dj = TrackDelayedJob.where("item_id = ?",args[0]).first
        if track_dj.nil?
            TrackDelayedJob.create(:delayed_job_id => dj.id, :item_id => args[0])
        else
            old_dj = Delayed::Job.find_by_id(track_dj.delayed_job_id)
            old_dj.destroy unless old_dj.nil?
            track_dj.update_attribute(:delayed_job_id, dj.id)
        end
    end

def self.send_digest(item_id)
#write your code to send digest.
end

end

c) When you want to update already set delayed job then

NewsLetter.update_delayed_job_time(item_id, time)

add this in NewsLetter class
def self.set_delayed_job_time(item_id, time)
   
        track_dj = TrackDelayedJob.where("item_id = ?", item_id).first
        dj = Delayed::Job.find_by_id(track_dj.delayed_job_id) unless track_dj.nil?
        unless dj.nil?
            #below code is required in case you want to convert hours and minutes
            #   time = "#{Date.today} #{hours}:#{minutes}".to_time           
            dj.run_at = time
            dj.save
        end
    end

end

No comments:

Post a Comment