[英]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.