Search code examples
ruby-on-railsdelayed-job

How to handle loop for delayed job


I add pdf generation task in delayed jobs like below

@employe.each do |em|
        em.details.each do |detail|
          Delayed::Job.enqueue GeneratePdf.new(detail)
        end
      end

This works fine but it takes like 2min to loop through all the employes and their details and to complete the request.

How can I reduce this time? Or how can I add the loop delayed job as well. My current generate pdf class

class GeneratePdf < Struct.new(:detail)
  def perform
    filename =  detail.id.to_s
    pdf = EmployeDetailsPdf.new(detail) #this generates a pdf
    pdf.render_file(filename + ".pdf")
  end
end

Solution

  • First off, I assume your @employe variable should be called @employees and stores just that: several employees

    You generally should only pass the id of an object to a job. The job will query the database to retrieve the employee. It does not matter if that takes a bit longer, that's what the job is here for.

    Like that, you pass the major work load to the job:

    # some_controller
    @employees.pluck(:id).each { |id| Delayed::Job.enqueue(id) }
    
    # generate_pdf_job.rb
    class GeneratePdf < Struct.new(:id)
      def perform
        employee = Employee.find(id)
    
        employee.details.each do |detail|
          pdf = EmployeDetailsPdf.new(detail)
          pdf.render_file(detail.id.to_s + ".pdf")
        end
      end
    end