这在我的控制器中工作正常。
def export_list_sites_as_csv
require "csv"
csv_string = CSV.generate do |csv|
csv << ["id","name", 'etc']
@search.relation.not_archived.each do |site|
csv << [site.id, site.name, site.etc]
end
end
send_data csv_string,
:type => 'text/csv',
:filename => '_sites.csv',
:disposition => 'attachment'
end
@search
变量取决于用户过滤器,在某种程度上会给 RAM 带来大量负载,UX 不好。因为其他请求将被搁置,直到当前请求得到服务。这也使我的系统挂起。因此,希望在后台进程运行,并在准备好下载后让用户知道。
当我尝试移动到模型时。
我收到一个错误 #<\Class:0x9f8bed0>send_data 的未定义方法"
我要搬到模型,因为我必须在上面调用延迟的工作。
首次处理 CSV 和延迟作业。
编辑:ActionController::Streaming
仅在控制器中可用,所以其他方式? 更多的时候,这不会去任何地方。
正如D-Side的回答所说,我将不得不寻找其他方法。
编辑2:按照我能够做的 http://railscasts.com/episodes/171-delayed-job
class ExportCsv < Struct(:site_ids, :user_id)
def perform
require "csv"
sites = Site.where(id: site_ids)
CSV.open("tmp/#{user_id}.csv", "w+") do |csv|
csv << ["id","name", 'etc']
sites.each do |site|
csv << ....
end
end
end
def after(job)
send_file(
....
)
end
end
如何在自定义类中使用ActionController::Streaming
ExportCsv
或 Model
编辑:
了解同步以及我如何处理这种情况,
答:http://imnithin.github.io/csv_download_with_delayed_job.html
你试图做的事情违背了延迟工作的目的。
当用户发出请求时,服务器应做出响应以完成请求。问题是,有些请求需要相当长的时间才能完成,用户必须坚持并等待完成。一个经典案例 - 大规模电子邮件传递,但正如您提到的,还有其他案例,例如数据套件生成。无论什么。完成所需的时间比用户等待的时间要长。
现在来了延迟工作。它执行某个操作,而无需响应查询的上下文。它不需要着急。但你不能只是为它打send_data
耳光:它不会有任何查询来响应。相反,它应该将完成的工作的结果写入一些持久存储中。
你有很多方法可以做到这一点。
- 当数据集准备就绪时,您可以通过电子邮件通知用户。您甚至可以将其附加到电子邮件中,但我不建议这样做:您不能依靠电子邮件提供商的准备来接受大量数据。改为创建用于下载数据集的链接并发送。
- DelayedJob 需要渲染数据集,将其保存到文件中,获取链接并将其通过电子邮件发送给用户。
- 将应用的某个部分(由模型、控制器和视图组成的公司)听起来像"已完成的请求",可能是用户个人资料的一部分。"启动"请求应指示用户稍后返回并查看该列表以获取结果。
- 在请求完成后,延迟作业必须在该列表中输入一个条目。数据集的存储方式无关紧要,但您可以将其与上述方法相结合,将其保存到文件中并显示指向它的链接。