簡體   English   中英

Rails - Paper_Clip - 支持多文件上傳

[英]Rails - Paper_Clip - Support for Multi File Uploads

我在我的Rails 3應用程序上安裝了paper_clip,並且可以上傳文件 - 哇這很有趣而且簡單!

現在的挑戰是,允許用戶上傳多個對象。 是否單擊選擇文件並能夠選擇多個文件。 或者單擊更多按鈕並獲取另一個文件上載按鈕。

我無法找到任何教程或寶石來支持這種開箱即用。 令人震驚我知道......

任何建議或解決方案。 似乎是一個共同的需求?

謝謝

好的,這是一個復雜的,但它是可行的。 以下是我如何使用它。

在客戶端,我使用了http://github.com/valums/file-uploader ,這是一個javascript庫,允許多個文件上傳,帶有進度條和拖放支持。 它受到良好支持,高度可配置,基本實現很簡單:

在視圖中:

<div id='file-uploader'><noscript><p>Please Enable JavaScript to use the file uploader</p></noscript></div>

在js中:

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完成的,它創建了一個新的Tempfile(記住:Heroku是只讀的):

# 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中:

config.middleware.use 'Rack::RawFileStubber'

然后在控制器中:

  def upload
    @foo = modelWithPaperclip.create({ :img => params[:file] })
  end

這種方法可靠,但在同時上傳大量文件時可能會很慢。

免責聲明

這是針對具有單個,已知且受信任的后端用戶的項目實現的。 它幾乎肯定會對高流量Heroku應用程序產生一些嚴重的性能影響,並且我沒有為安全性進行過防火測試。 那說,它絕對有效。

Ryan Bigg建議的方法是:

Daniel Mendel的file-uploader推薦非常棒。 這是一個非常棒的用戶體驗,比如Gmail拖放上傳。 如果你對最新的中間件組件感興趣,有人寫了一篇關於如何使用rack-raw-upload中間件連接rails應用程序的博客文章。

還有一個最近更新的插件可能很有用

另一個(包括完整性。我沒有調查過這個。)

這些問題高度相關

在Action的第8章中的Rails 3中介紹了這一點。但我沒有介紹上傳到S3或調整圖像大小。

建議你單獨購買它來解決這個問題可能聽起來有點偏頗,但我可以保證你會回答你的其他問題。 它將行為驅動開發方法作為主要主題之一,在開發應用程序期間向您介紹Rails功能。 這不僅向您展示了如何構建應用程序,還使其可維護

至於上傳后的圖像大小調整,Paperclip有相當好的文檔 如果您不理解任何選項/方法,我建議您閱讀,然后在SO上提出另一個問題。

至於S3上傳,你可以這樣做:

has_attached_file :photo, :styles => { ... }, :storage => :s3

您需要使用S3詳細信息配置Paperclip::Storage::S3以進行設置,Paperclip再次為此提供了一些非常棒的文檔

祝好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM