我正在Ruby on Rails上传文件到服务器
通常情况下,它是一个文本文件,我将其作为“文件”字段保存在模型中,提交ActiveRecord以及其他字段,如提交标题等。
但是,用户也可以提交zip文件。在这种情况下,zip文件应该解压缩,并且对于zip中的每个文件,应该使用相同的文本字段创建新的提交,但是当前文件。
我该如何做到这一点?
我查看了网络上的解压缩示例,但大多数都使用目录来解压缩文件。我不确定我是否需要它,因为在当前的SubmissionsController创建方法中,接收到一个文件对象,并且我认为保存文件的路径是在调用Submission save方法时自动生成的。所以我想也许我应该将zip文件解压缩到内存中以获取文件对象数组,然后使用每个文件对象创建一个新的Submission但是相同的字段然后让ActiveRecord在将它们保存到每个文件时生成每个文件路径的文件路径。数据库。 我可能在这里错了,因为我对Rails和Ruby都不熟悉。
答案 0 :(得分:41)
我会使用rubyzip gem。特别是这部分:https://github.com/rubyzip/rubyzip/blob/master/lib/zip/filesystem.rb
它在内存中创建一个人工文件系统,镜像zip文件的内容。以下是基于文档示例的示例:
Rubyzip interface changed!!! No need to do require "zip/zip" and Zip prefix in class names removed.
require 'zip'
Zip::File.open("my.zip") do |zipfile|
zipfile.each do |file|
# do something with file
end
end
在您的情况下,只需将上传的临时文件的名称放在示例中my.zip
的位置,您就可以遍历内容并对它们进行常规操作。
答案 1 :(得分:25)
从RubyZip项目页面:
Rubyzip界面改变了!无需在列名中删除“zip / zip”和Zip前缀。
因此,来自@ ben-lee的示例代码应该更新为:
require 'zip'
Zip::File.open("my.zip") do |zipfile|
zipfile.each do |file|
# do something with file
end
end
答案 2 :(得分:15)
安装rubyzip
gem之后,您可以使用此方法提取zip文件:
$result = $db->query('SELECT * FROM `bets` WHERE `user` = 76561198223084096');
$row_cnt = $result->mysql_num_rows;
printf("Result set has %d rows.\n",$row_cnt);
您可以这样使用:
require 'zip'
def extract_zip(file, destination)
FileUtils.mkdir_p(destination)
Zip::File.open(file) do |zip_file|
zip_file.each do |f|
fpath = File.join(destination, f.name)
zip_file.extract(f, fpath) unless File.exist?(fpath)
end
end
end
答案 3 :(得分:0)
为我工作:
gem install rubyzip
main.rb
require 'zip'
def extract_zip(file, destination)
FileUtils.mkdir_p(destination)
Zip::File.open(file) do |zip_file|
zip_file.each do |f|
fpath = File.join(destination, f.name)
FileUtils.mkdir_p(File.dirname(fpath))
zip_file.extract(f, fpath) unless File.exist?(fpath)
end
end
end
extract_zip('file.zip', 'tmp')