Ruby-on-rails 没有activerecord的文件上传
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1676195/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
file upload without activerecord
提问by Mike
How do you handle file upload in rail without attaching them to active record ?
I just want to write the files to the disk.
如何在不将文件附加到活动记录的情况下处理 rail 中的文件上传?
我只想将文件写入磁盘。
Thanks,
谢谢,
回答by Rytis Luko?evi?ius
If I understand correctly what you need then the most simple example would be this:
如果我正确理解你需要什么,那么最简单的例子就是:
The controller:
控制器:
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
The view:
风景:
<% 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 %>
This would let you upload any file without any checks or validations which in my opinion isn't that usefull.
这将使您无需任何检查或验证即可上传任何文件,这在我看来并不是那么有用。
If I would do it myself then I would use something like validatable gemor tableless gemjust tableless is not supported anymore. These gems would allow you to validate what you're uploading to make it more sane.
如果我自己做,那么我会使用类似validatable gem或tableless gem 之类的东西,只是不再支持tableless。这些 gem 将允许您验证您上传的内容,使其更加理智。
回答by Felipe M Andrada
You can just move the temporary file to destiny path using FileUtils
您可以使用 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
回答by chbrown
The Tempfiledocumentation shows an example that's equivalent to Rytis's code, which is fine most of the time. But when you call tempfile.read, Ruby is reading the whole file as a single chunk into memory, which is sub-optimal.
该Tempfile文档显示了一个与 Rytis 代码等效的示例,大多数情况下都很好。但是当您调用 时tempfile.read,Ruby 会将整个文件作为单个块读取到内存中,这是次优的。
However, FileUtilsprovides a copy_streammethod, and IO, at least in Ruby 2.0, provides a copy_streamimplementation that handles writing directly to a filepath (FileUtils.copy_streamrequires File-like objects on both sides, or so say the docs).
但是,FileUtils提供了一种copy_stream方法,并且IO,至少在 Ruby 2.0 中,提供了一种copy_stream处理直接写入FileUtils.copy_stream文件路径的实现(双方都需要类 File 对象,或者说文档)。
In my case, I was initiating a large multi-file upload via AJAX, and wanted to avoid reading the whole file(s) into Ruby's memory before writing to disk.
就我而言,我正在通过 AJAX 启动大型多文件上传,并希望避免在写入磁盘之前将整个文件读入 Ruby 的内存。
In the example below, params[:files]is an Arrayof ActionDispatch::Http::UploadedFileinstances, and local_filepathis a string pointing to a non-existing file in an existing directory. For brevity, I'll assume I'm only uploading one file:
在下面的例子中,params[:files]是一个Array的ActionDispatch::Http::UploadedFile情况下,并且local_filepath是一个指向不存在的文件中的现有目录字符串。为简洁起见,我假设我只上传一个文件:
IO.copy_stream(params[:files][0].tempfile, local_filepath)
The ActionDispatch::Http::UploadedFileinstance has a .tempfilefield that's just a regular Tempfileinstance.
该ActionDispatch::Http::UploadedFile实例有一个.tempfile字段,它只是一个常规Tempfile实例。
I'm not actually sure that Ruby still isn't reading the whole file into memory—I didn't benchmark anything—but it's a lot more possible than it is with the localfile.write(tempfile.read)syntax.
我实际上不确定 Ruby 仍然没有将整个文件读入内存——我没有对任何东西进行基准测试——但这比使用localfile.write(tempfile.read)语法更有可能。
tl;dr: IO.copy_stream(your_tempfile, your_disk_filepath)is more concise, if not faster.
tl;dr:IO.copy_stream(your_tempfile, your_disk_filepath)如果不是更快,则更简洁。
回答by kafuchau
You could try using the Rails plugin Attachment_futo handle file uploads. It allows you to save uploads to the file system instead of the database.
您可以尝试使用 Rails 插件Attachment_fu来处理文件上传。它允许您将上传内容保存到文件系统而不是数据库。

