【问题标题】:file upload without activerecord没有活动记录的文件上传
【发布时间】:2010-12-13 20:36:15
【问题描述】:

如何在不将文件附加到活动记录的情况下处理文件上传?
我只想将文件写入磁盘。

谢谢,

【问题讨论】:

标签: ruby-on-rails


【解决方案1】:

如果我正确理解您的需求,那么最简单的例子就是:

控制器:

  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 之类的东西,只是不再支持无表。这些 gem 可以让您验证您上传的内容,使其更加合理。

【讨论】:

  • 只要确保在 rails 3 中使用 。
  • 为了保持一致,您不应该使用File.join("public", "images", "upload") 创建directory吗?
  • 当然,这是一个很好的提示。很久以前写过这个:) 不要以为我当时不知道该怎么做:) 只是在编码时使用了示例,所以在一行中我使用它:))另一方面我不知道。现在更新。
【解决方案2】:

Tempfile 文档显示了一个与 Rytis 的代码等效的示例,大多数情况下都可以。但是当您调用tempfile.read 时,Ruby 会将整个文件作为单个块读取到内存中,这是次优的。

然而,FileUtils 提供了一个copy_stream 方法,而IO,至少在 Ruby 2.0 中,提供了一个处理直接写入文件路径的copy_stream 实现(FileUtils.copy_stream 在两者上都需要类似文件的对象双方,或者说文档)。

就我而言,我通过 AJAX 启动大型多文件上传,并希望避免在写入磁盘之前将整个文件读入 Ruby 的内存。

在下面的示例中,params[:files]ArrayActionDispatch::Http::UploadedFile 实例,local_filepath 是指向现有目录中不存在文件的字符串。为简洁起见,我假设我只上传一个文件:

IO.copy_stream(params[:files][0].tempfile, local_filepath)

ActionDispatch::Http::UploadedFile 实例有一个 .tempfile 字段,它只是一个普通的 Tempfile 实例。

我实际上并不确定 Ruby 是否仍然没有将整个文件读入内存——我没有进行任何基准测试——但它比使用 localfile.write(tempfile.read) 语法更有可能。

tl;drIO.copy_stream(your_tempfile, your_disk_filepath) 更简洁,甚至更快。

【讨论】:

    【解决方案3】:

    您可以使用 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
    

    【讨论】:

      【解决方案4】:

      您可以尝试使用 Rails 插件Attachment_fu 来处理文件上传。它允许您将上传内容保存到文件系统而不是数据库。

      【讨论】:

        猜你喜欢
        • 2012-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-20
        • 1970-01-01
        相关资源
        最近更新 更多