Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controller Action to Delayed Job

I am uploading a tab-delimited document and processing in the controller. Everything works fine, but can take some time on a large file. I want to move this to a delay_job, which I have working elsewhere in my app, but as this is in the controller, cannot be called in the same way.

The form calls on the process_file action, which in turn calls on the salesupload action. How should I turn this into a background job?

class SalesController < ApplicationController

  def salesupload(file)
    uploaded_io = file.read
    numrows = "uploaded_io.size"
    FasterCSV.parse(uploaded_io, {:headers => true, :col_sep =>"\t"}).each do |row_data|
        full, upc, _discard, isrc = row_data[26].match(/^([^_]+)(_(.+))?/).to_a
          new_record = AppleSale.new(
              'provider' =>  row_data[0],
              'provider_country' => row_data[1],
              'vendor_identifier' => row_data[2]
          )
      new_record.save
    end
  end

    def process_file
        file = params[:apple_sale][:tsv_file]
        salesupload(file)
    end

end
like image 865
user1756535 Avatar asked Oct 18 '12 14:10

user1756535


1 Answers

I found when I had to do this that the method defined in the controller has to be a class method. I can't remember why this was, I think it had to do with having a more explicit receiver. So what I would do is make the salesupload method a class method, and then just call .delay on it.

def self.salesupload(files)
  # code
end

def process_file
  file = params[:apple_sale][:tsv_file]
  SalesController.delay.salesupload(file)
  head :no_content
end

And you should be good to go! I also made my original method (process_file in this case) called via AJAX, and then I appended the head :no_content so that it returned something without needing a redirect or anything.

like image 123
MrDanA Avatar answered Sep 29 '22 15:09

MrDanA