8

我正在上传一个制表符分隔的文档并在控制器中进行处理。一切正常,但处理大文件可能需要一些时间。我想把它移到一个delay_job,我在我的应用程序的其他地方工作,但由于它在控制器中,不能以同样的方式调用。

该表单调用 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
4

3 回答 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它以便它返回一些东西而不需要重定向或任何东西。

于 2012-10-18T14:22:34.570 回答
2

我写了一个名为delayed_action的gem来做到这一点。

在这种情况下,你会写 delayed_action [:sales_upload]

就是这样。

于 2016-01-09T00:06:56.323 回答
1

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

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

但基本上,在设置延迟作业后,您只需使用 send_later(:process_file) 之类的东西来告诉在后台运行该项目。这非常简单,您的命令和数据结构将保存在数据库表中,稍后一个单独的进程可以执行它。我想在观看 railscast 之后,您会得到答案;)

于 2012-10-18T14:28:01.187 回答