0

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?

1 Answer 1

3

You're right, it's because of render. When you're setting headers, and then finally call render, 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 the ActionController::DoubleRenderError.

One way to send multiple .csv files at once is to combine them into a single .zip file and send that instead of the raw .csv files. There is an excellent, very easy to use rubyzip gem you can use to build your .zip file.

Instead of calling render inside stream_csv, you can simply return the FasterCSV instance 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 the README at the gem above).

Finally, instead of setting so many headers to force the download, take a look at Rails send_file method

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your help that contains very clear explaination :)
Glad to help, and good for you for sorting the code out on your own.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.