Search code examples
ruby-on-railsdelayed-jobrails-activejob

Using delayed job to process a method in background


Rails 5.1

I have the following in my gemfile

gem 'delayed_job'
gem 'delayed_job_active_record'
gem 'daemons'

I installed/updated the gems

Then I did:

rails generate delayed_job:active_record

This generated two files in bin called delayed_jobs.rb and created the migration files.

I added the following to config/application.rb:

config.active_job.queue_adapter = :delayed_job

I have a controller, with an action, that takes an already uploaded csv file, parses it, and populates the DB with the data. I want that method, or specifically, part of that method to be processed in the background.

The method is:

def process_parsed_spreadsheet
  temp_file_path = params[:temp_file_path]
  @spreadsheet   = helpers.open_worksheet(temp_file_path)
  number_of_rows = @spreadsheet.count - 1

  helpers.process_spreadsheet(number_of_rows, @spreadsheet, params[:followed_id])
  helpers.remove_uploaded_file(temp_file_path)

  redirect_to root_path, notice: t('fw_exports.file_successfully_processed')
end

I am lost on how to use delayed_jobs to process this method in the background. I read up about having a model, and then having one of the methods in that model process in the background, but this is different.

Solution (based on the answer below):

I added the following:

app/jobs/parse_and_process_spreadsheet_job.rb

class ParseAndProcessSpreadsheetJob < ApplicationJob
  queue_as :default

  def perform(temp_file_path, followed_id)
    @spreadsheet = helpers.open_worksheet(temp_file_path)
    number_of_rows = @spreadsheet.count - 1
    helpers.process_spreadsheet(number_of_rows, @spreadsheet, followed_id)
    helpers.remove_uploaded_file(temp_file_path)
    redirect_to root_path, notice: t('fw_exports.file_successfully_processed')
  end
end

And my app/controllers/fw_exports_controller.rb:

def process_parsed_spreadsheet
  ParseAndProcessSpreadsheetJob.perform(params[:temp_file_path], params[:followed_id])
end

Solution

  • According to the documentation, you should be able to add handle_asynchronously :process_parsed_spreadsheet after your class method.

    When I've used active_job, I generally create a new file in app/jobs e.g. process_spreadsheet_job.rb and then create a new class that inherits from ApplicationJob. Here's a minimal example:

    class ProcessSpreadsheetJob < ApplicationJob
    
        queue_as :default
    
        def perform(temp_file_path:)
            # Your custom method here.
        end
    end
    

    Then you can call ProcessSpreadsheetJob.perform_later() in your application controller and have a job added to the queue.