すべてのレシートファイルデータを含むzipファイルをダウンロードしようとしているときに、Herokuで頭を悩ませてきました。
ファイルはAmazons3に保存されており、すべて私の開発マシンで正常に動作します。
私はそれがTempfileに関係していると思い、herokuのファイルシステムにいくつかの厳格なポリシーがあるため、以前の解決策を放棄しました。そこで、tmpフォルダーを使用しましたが、問題はないようです。すでにs3から(openUriを使用して)zipファイルに直接ロードしようとしましたが、Herokuでも機能しないようです。
Herokuのコードがファイルをzipにロードしないのは何が問題なのですか?
これが私のモデルメソッドです:
def zip_receipts(search_hash=nil)
require 'zip/zip'
require 'zip/zipfilesystem'
t=File.open("#{Rails.root}/tmp/#{Digest::MD5.hexdigest(rand(12).to_s)}_#{Process.pid}",'w')
# t = Tempfile.new(Digest::MD5.hexdigest(rand(12).to_s))
# Give the path of the temp file to the zip outputstream, it won't try to open it as an archive.
Zip::ZipOutputStream.open(t.path) do |zos|
logger.debug("search hash Zip: #{search_hash.inspect}")
self.feed(search_hash).each do |receipt|
begin
require 'open-uri'
require 'tempfile'
#configures filename
filen = File.basename(receipt.receipt_file_file_name)
ext= File.extname(filen)
filen_noext = File.basename(receipt.receipt_file_file_name, '.*')
filen=filen_noext+SecureRandom.hex(10)+ext
logger.info("Info Zip - Filename: #{filen}")
# Create a new entry on the zip file
zos.put_next_entry(filen)
# logger.info("Info Zip - Added entry: #{zos.inspect}")
# Add the contents of the file, reading directly from amazon
tfilepath= "#{Rails.root}/tmp/#{File.basename(filen,ext)}_#{Process.pid}"
open(tfilepath,"wb") do |file|
file << open(receipt.authenticated_url(:original),:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE).read
end
zos.print IO.binread tfilepath
# logger.info("Info Zip - Extracted from amazon: #{zos.inspect}")
rescue Exception => e
logger.info("exception #{e}")
end # closes the exception begin
end #closes receipts cycle
end #closes zip file stream cycle
# The temp file will be deleted some time...
t.close
#returns the path for send file controller to act
t.path
end
私のコントローラー:
def download_all
@user = User.find_by_id(params[:user_id])
filepath = @user.zip_receipts
# Send it using the right mime type, with a download window and some nice file name.
send_file(filepath,type: 'application/zip', disposition: 'attachment',filename:"MyReceipts.zip")
end
また、ビューとルートも記述して、すべてのダウンロード機能を実装しようとしている他の人に役立つようにします。
ルート.rb
resources :users do
post 'download_all'
end
私の見解
<%= link_to "Download receipts", user_download_all_path(user_id:user.id), method: :post %>