rubyruby-on-rails-4httparty

Ruby on Rails - Zip/HTTParty


I have an api request that returns multiple (Word) files to-be-downloaded, but I can't send_data IN the while loop, else I'll get the dreaded Multiple Renders error, so my question is how can I package/combine/zip/parse the multiple so that I can send_data just once?

Here's the block:

def generate_multi_letter(template, letterName, params)
@Document_URL = "#{ENV["API_HOST"]}/api/StateDocument/GenerateDocX/#{template}"
response = HTTParty.post(@Document_URL,
                         :body => params,
                         :headers => { "Content-Type" => "application/json" })

Zip::InputStream.open(StringIO.new(response)) do |io|
while entry = io.get_next_entry
            report = io.read
            send_data report,
              :filename => letterName + ".docx",
              :type => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
              disposition: "attachment"
          end

#or maybe something more like.....?

Zip::File.open(response, Zip::File::CREATE) do |zip|
  Attachment.all.each do |attachment|
    file = Tempfile.new("#{attachment.created_at.in_time_zone}.docx")
    file.write(attachment.image_string)
    zipfile.add("#{attachment.created_at.in_time_zone}.docx", file.path)
  end
end

zip_data = File.read(response)
send_data(zip_data, type: 'application/zip', disposition: 'attachment', filename: letterName + ".docx")

I'm also getting "path name contains null byte" errors, if anyone spots where I'm going wrong there??


Solution

  • For any who follow, this turned out to be surprisingly easy, just trust the browser, and return the whole response (so long as you define the mime type as .zip):

    @URL = "#{ENV["API_HOST"]}/api/GenerateDocX/#{template}"
    response = HTTParty.post(@URL,:body => params,:headers => { "Content-Type" => "application/json" })
    
    send_data response, :filename => letterName + ".zip", type: 'application/zip'