This works fine in my controller.
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 variable depends on the user filter, to the extent that there will be a lot of RAM load , UX is not very good. Because other requests will be suspended until the current request is submitted. Which also makes my system freeze. Therefore, you want to start the background process and tell the user when he will be ready to download.
When I try to switch to a model.
I get an error undefined method `send_data 'for # <\ Class: 0x9f8bed0>
I turn to the model because I have to call delayed work.
Work with CSV and Delayed Job for the first time.
Edit: ActionController::Streaming is only available in the controller so otherwise? more often or not, this is not going anywhere.
As the answer of D-Side says, I have to look for other ways.
Edit2: After http://railscasts.com/episodes/171-delayed-job I was able to do
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
How to use ActionController::Streaming inside custom class ExportCsv or Model
Edit:
Understanding synchronization and how I dealt with the situation,
Answer : http://imnithin.imtqy.com/csv_download_with_delayed_job.html