如何处理铁路上的文件上传而不将其附加到活动记录? 我只是想把文件写到磁盘上。
谢谢,
答案 0 :(得分:56)
如果我理解你需要什么,那么最简单的例子是:
控制器:
class UploadController < ApplicationController
def new
end
def create
name = params[:upload][:file].original_filename
path = File.join("public", "images", "upload", name)
File.open(path, "wb") { |f| f.write(params[:upload][:file].read) }
flash[:notice] = "File uploaded"
redirect_to "/upload/new"
end
end
观点:
<% flash.each do |key, msg| %>
<%= content_tag :div, msg, :class => [key, " message"], :id => "notice_#{key}" %>
<% end %>
<% form_tag '/upload/create', { :multipart => true } do %>
<p>
<%= file_field_tag 'upload[file]' %>
</p>
<p>
<%= submit_tag "Upload" %>
</p>
<% end %>
这样您就可以上传任何文件而无需任何检查或验证,我认为这些检查或验证不是很有用。
如果我自己这样做,那么我会使用像validatable gem或tableless gem这样的东西,只是不再支持无表格。这些宝石将允许您验证您上传的内容,使其更加清晰。
答案 1 :(得分:4)
您可以使用FileUtils
将临时文件移动到命运路径tmp = params[:my_file_field].tempfile
destiny_file = File.join('public', 'uploads', params[:my_file_field].original_filename)
FileUtils.move tmp.path, destiny_file
答案 2 :(得分:3)
Tempfile
文档显示了一个与Rytis代码等效的示例,这在大多数情况下都很好。但是当你调用tempfile.read
时,Ruby会将整个文件作为单个块读入内存,这是次优的。
但是,FileUtils
提供了copy_stream
方法,IO
至少在Ruby 2.0中提供了一个copy_stream
实现,它可以直接处理文件路径({{ 1}}要求双方都有类似文件的对象,或者说文档)。
就我而言,我是通过AJAX启动大型多文件上传,并希望在写入磁盘之前避免将整个文件读入Ruby的内存。
在下面的示例中,FileUtils.copy_stream
是params[:files]
Array
个实例,ActionDispatch::Http::UploadedFile
是指向现有目录中不存在的文件的字符串。为简洁起见,我假设我只上传了一个文件:
local_filepath
IO.copy_stream(params[:files][0].tempfile, local_filepath)
个实例有一个ActionDispatch::Http::UploadedFile
字段,它只是一个普通的.tempfile
个实例。
我真的不确定Ruby是否仍然没有将整个文件读入内存 - 我没有对任何内容进行基准测试 - 但它比{更多可能'更有可能{1}}语法。
tl; dr :Tempfile
更简洁,如果不是更快。
答案 3 :(得分:0)
您可以尝试使用Rails插件Attachment_fu来处理文件上传。它允许您将上传保存到文件系统而不是数据库。