控制器操作转延迟任务(Delayed Job)

8

我正在上传一个制表符分隔的文档并在控制器中处理。一切都正常工作,但对于大文件可能需要一些时间。我想将其移动到延迟作业中,在我的应用程序的其他地方已经有了这个工作,但是由于这是在控制器中,无法以相同的方式调用。

该表单调用process_file操作,该操作又调用salesupload操作。我应该如何将其转换为后台作业?

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
3个回答

10

我发现当我需要这样做时,控制器中定义的方法必须是类方法。我记不清为什么了,但我认为这与有一个更明确的接收者有关。所以我会将salesupload方法变成一个类方法,然后只需在其上调用.delay即可。

def self.salesupload(files)
  # code
end

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

然后你就准备好了!在我的原始方法(在这种情况下是process_file)通过 AJAX 调用后,我追加了 head:no_content,以便返回某些内容而无需重定向或其他操作。


2
我写了一个叫做 delayed_action 的 gem 来实现这个功能。
在这种情况下,你只需要编写以下代码: delayed_action [:sales_upload] 就这样。

1

我想你应该将这段代码移动到一个模型或者一个单独的类中(例如在lib文件夹内)。但这只是组织和最佳实践的问题。

关于在后台运行此代码,您有很多选择。如果您想使用delayed_job,我想您应该观看这个视频教程: http://railscasts.com/episodes/171-delayed-job

但基本上,在设置好delayed job之后,您只需要使用类似send_later(:process_file)的命令告诉它在后台运行该项目即可。这非常简单明了,您的命令和数据结构将保存在数据库表中,稍后一个单独的进程可以执行它。我想在观看完这个视频教程后,您会得到答案的;)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接