首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails - Paper_Clip -支持多文件上传

Rails - Paper_Clip -支持多文件上传
EN

Stack Overflow用户
提问于 2010-10-23 06:19:48
回答 3查看 2.2K关注 0票数 5

我已经在我的Rails3应用程序上安装了paper_clip,可以上传文件-哇,这很有趣,也很容易!

现在的挑战是,允许用户上传多个对象。无论是点击select fileS还是能够选择多个。或者单击更多按钮并获得另一个文件上传按钮。

我找不到任何开箱即用的教程或宝石来支持这一点。令人震惊的我知道..。

任何建议或解决方案。似乎是一种普遍的需求?

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-10-23 07:56:28

好吧,这是一个复杂的问题,但它是可行的。下面是我是如何让它工作的。

在客户端,我使用了http://github.com/valums/file-uploader,这是一个支持进度条和拖放的javascript库,允许多次上传文件。它得到了很好的支持,高度可配置性,并且基本实现很简单:

在视图中:

代码语言:javascript
复制
<div id='file-uploader'><noscript><p>Please Enable JavaScript to use the file uploader</p></noscript></div>

在js中:

代码语言:javascript
复制
var uploader = new qq.FileUploader({
   element: $('#file-uploader')[0],
   action: 'files/upload',
   onComplete: function(id, fileName, responseJSON){
     // callback
   }
});

当提交文件时,FileUploader将它们作为XHR请求发布到服务器,其中POST正文是原始文件数据,而头部和文件名在URL字符串中传递(这是通过javascript异步上传文件的唯一方法)。

这就是事情变得复杂的地方,因为Paperclip不知道如何处理这些原始请求,你必须捕获它们并将其转换回标准文件(最好在它们命中你的Rails应用程序之前),这样Paperclip才能发挥它的魔力。这是通过一些Rack Middleware来完成的,它会创建一个新的临时文件(记住: Heroku是只读的):

代码语言:javascript
复制
# Embarrassing note: This code was adapted from an example I found somewhere online
# if you recoginize any of it please let me know so I pass credit.
module Rack
  class RawFileStubber

    def initialize(app, path=/files\/upload/) # change for your route, careful.
      @app, @path = app, path
    end

    def call(env)
      if env["PATH_INFO"] =~ @path
        convert_and_pass_on(env)
      end
      @app.call(env)
    end

    def convert_and_pass_on(env)
      tempfile = env['rack.input'].to_tempfile      
      fake_file = {
        :filename => env['HTTP_X_FILE_NAME'],
        :type => content_type(env['HTTP_X_FILE_NAME']),
        :tempfile => tempfile
      }
      env['rack.request.form_input'] = env['rack.input']
      env['rack.request.form_hash'] ||= {}
      env['rack.request.query_hash'] ||= {}
      env['rack.request.form_hash']['file'] = fake_file
      env['rack.request.query_hash']['file'] = fake_file
      if query_params = env['HTTP_X_QUERY_PARAMS']
        require 'json'
        params = JSON.parse(query_params)
        env['rack.request.form_hash'].merge!(params)
        env['rack.request.query_hash'].merge!(params)
      end
    end

    def content_type(filename)
      case type = (filename.to_s.match(/\.(\w+)$/)[1] rescue "octet-stream").downcase
      when %r"jp(e|g|eg)"            then "image/jpeg"
      when %r"tiff?"                 then "image/tiff"
      when %r"png", "gif", "bmp"     then "image/#{type}"
      when "txt"                     then "text/plain"
      when %r"html?"                 then "text/html"
      when "js"                      then "application/js"
      when "csv", "xml", "css"       then "text/#{type}"
      else 'application/octet-stream'
      end
    end
  end
end

稍后,在application.rb中:

代码语言:javascript
复制
config.middleware.use 'Rack::RawFileStubber'

然后在控制器中:

代码语言:javascript
复制
  def upload
    @foo = modelWithPaperclip.create({ :img => params[:file] })
  end

虽然当同时上传大量文件时,这可能是一个缓慢的过程,但它的工作可靠。

免责声明

这是为一个只有一个已知和受信任的后端用户的项目实现的。对于一个高流量的Heroku应用程序来说,它几乎肯定会有一些严重的性能影响,我还没有对它进行安全性测试。这就是说,它肯定是有效的。

票数 5
EN

Stack Overflow用户

发布于 2012-03-13 05:12:39

Ryan Bigg推荐的方法如下:

Daniel Mendel的file-uploader推荐真的很棒。这是一个非常棒的用户体验,就像Gmail的拖放上传一样。如果你对最新的中间件组件感兴趣,有人写了一篇关于如何使用rack-raw-upload中间件将其与rails应用程序绑定的博客文章。

还有一个最近更新的插件,它可能会很有用

和另一个(为了完整性而包含)。我还没有调查过这个问题。)

这些问题高度相关。

票数 4
EN

Stack Overflow用户

发布于 2010-10-23 07:16:16

我会在Rails 3 in Action的第8章中介绍这一点,但是我不会介绍上传到S3或者调整图片大小。

仅仅因为解决这个问题而建议你购买它可能听起来有点偏颇,但我可以向你保证,它将回答你以后遇到的其他问题。它的主要主题之一是行为驱动开发方法,在应用程序的开发过程中向您介绍Rails特性。这不仅向您展示了如何构建应用程序,而且还展示了它的可维护性。

至于图片上传后的大小调整,Paperclip提供了pretty good documentation on that。我建议先读一读,然后再问另一个问题,这样如果你不理解任何选项/方法。

至于S3上传,你可以这样做:

代码语言:javascript
复制
has_attached_file :photo, :styles => { ... }, :storage => :s3

你需要用你的S3详细信息来配置Paperclip::Storage::S3才能设置它,同样,Paperclip也提供了一些pretty awesome documentation

祝好运!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4001376

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档