将Paperclip文件下载为ZIP

时间:2012-02-13 15:36:24

标签: ruby-on-rails zip paperclip

实际上我正在做这样的事情:

project          = Project.find(params[:id])  
attachments_list = project.attachments.where{attach_file_size > 0}
assets_list      = project.assets.where{image_file_size > 0}
#Person.where{(name =~ 'Ernie%') & (salary < 50000) | (name =~ 'Joe%') & (salary > 100000)}
file_name  = project.title.downcase.gsub(' ', '_destroy')
file_name  = "#{file_name}.zip"

temp_file  = Tempfile.new("#{file_name}-#{current_user.id}")
Zip::ZipOutputStream.open(temp_file.path) do |zos|
  attachments_list.each do |file|
    zos.put_next_entry(file.title)
    zos.print IO.read(file.attach.path)
  end
  assets_list.each do |file|
    zos.put_next_entry(file.title)
    zos.print IO.read("#{file.image.path}")
  end
end

send_file temp_file.path, :type => 'application/zip',
                          :disposition => 'attachment',
                          :filename => file_name
temp_file.close

这是有效的,但收到的文件上缺少扩展名,不知道吗?

3 个答案:

答案 0 :(得分:2)

我最终在相关模型中创建了一个方法,以返回带有扩展名

的文件名
def title_with_ext
    "#{self.title}#{File.extname(self.image.path)}"
end

答案 1 :(得分:1)

我做了类似的事情,但需要从S3而不是本地系统中获取文件。我的文件不大,所以我决定将它们加载到内存中。所以不要这样:

zos.print IO.read(file.attach.path)

我添加了require "open-uri",然后执行了此操作:

zos.print open(asset.data.url) {|f| f.read}

其中asset是回形针对象。

答案 2 :(得分:0)

只需将:filename => file_name更改为:filename => file_name.zip

即可

:type仅指定将使用该文件的应用程序,但不指定文件名的扩展名