没有activerecord的文件上传

时间:2009-11-04 19:55:23

标签: ruby-on-rails

如何处理铁路上的文件上传而不将其附加到活动记录? 我只是想把文件写到磁盘上。

谢谢,

4 个答案:

答案 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 gemtableless 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_streamparams[: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来处理文件上传。它允许您将上传保存到文件系统而不是数据库。