I am very new to ruby. I have a question that how can I export two files within one click.
In the exsiting version, I can generate only one file at a time by calling 'def stream_csv', but when I try to call it twice in order to get two files, I got an error indicating about "ActionController::DoubleRenderError (Can only render or redirect once per action):" I guess, it is because of render.
Here is the source code of stream_csv:
def stream_csv
require 'fastercsv'
filename = params[:action] + ".csv"
#this is required if you want this to work with IE
if request.env['HTTP_USER_AGENT'] =~ /msie/i
headers['Pragma'] = 'public'
headers["Content-type"] = "text/plain"
headers['Cache-Control'] = 'no-cache, must-revalidate, post-check=0, pre-check=0'
headers['Content-Disposition'] = "attachment; filename=\"#{filename}\""
headers['Expires'] = "0"
else
headers["Content-Type"] ||= 'text/csv'
headers["Content-Disposition"] = "attachment; filename=\"#{filename}\""
controller.response.headers["Content-Transfer-Encoding"] = "binary"
end
render :text => Proc.new { |response, output|
csv = FasterCSV.new(output, :row_sep => "\r\n")
yield csv
}
end
end
Is it possible to create two files under one click? If yes, how can I do it?
You're right, it's because of
render. When you're settingheaders, and then finally callrender, you're building up an HTTP response to be sent to the browser. You can't do this twice from one HTTP request, which is why you get theActionController::DoubleRenderError.One way to send multiple
.csvfiles at once is to combine them into a single.zipfile and send that instead of the raw.csvfiles. There is an excellent, very easy to userubyzipgem you can use to build your.zipfile.Instead of calling render inside
stream_csv, you can simply return theFasterCSVinstance itself or it's String output. From the calling method you can build up a .zip file (I'm not including code for that here since I'd just be copying and pasting from theREADMEat the gem above).Finally, instead of setting so many headers to force the download, take a look at Rails
send_filemethod