我正在上传制表符分隔的文档并在控制器中处理。一切正常,但可能需要一些时间在一个大文件上。我想把它移到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
答案 0 :(得分:9)
我发现当我必须这样做时,控制器中定义的方法必须是类方法。我不记得为什么会这样,我认为这与拥有更明确的接收器有关。所以我要做的是使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
你应该好好去!我也通过AJAX调用了我的原始方法(在这种情况下为process_file
),然后我附加了head :no_content
,以便它返回一些东西而不需要重定向或任何东西。
答案 1 :(得分:2)
答案 2 :(得分:1)
我想你应该把这段代码移到一个模型或一个单独的类中(例如在lib文件夹中)。但这只是组织和最佳实践的问题。
关于在后台运行此代码,您有很多选择。 如果你想使用delayed_job我猜你应该看这个截屏视频: http://railscasts.com/episodes/171-delayed-job
但基本上,在设置延迟作业后,您只需使用send_later(:process_file)之类的东西来告诉在后台运行该项目。 它非常简单,您的命令和数据结构将保存在数据库表中,之后分离的进程可以执行它。我想在看完轨道广播之后你会得到你的答案;)