use*_*959 5 ruby-on-rails paperclip ruby-on-rails-3
我在我的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>
Run Code Online (Sandbox Code Playgroud)
在js中:
var uploader = new qq.FileUploader({
element: $('#file-uploader')[0],
action: 'files/upload',
onComplete: function(id, fileName, responseJSON){
// callback
}
});
Run Code Online (Sandbox Code Playgroud)
当递文件,FileUploader它们张贴到服务器的XHR请求,其中POST主体是原始文件数据,而头和文件名的URL字符串传递(这是上传通过JavaScript asyncronously文件的唯一方法).
这是它变得复杂的地方,因为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
Run Code Online (Sandbox Code Playgroud)
稍后,在application.rb中:
config.middleware.use 'Rack::RawFileStubber'
Run Code Online (Sandbox Code Playgroud)
然后在控制器中:
def upload
@foo = modelWithPaperclip.create({ :img => params[:file] })
end
Run Code Online (Sandbox Code Playgroud)
这种方法可靠,但在同时上传大量文件时可能会很慢.
免责声明
这是针对具有单个,已知且受信任的后端用户的项目实现的.它几乎肯定会对高流量Heroku应用程序产生一些严重的性能影响,并且我没有为安全性进行过防火测试.那说,它绝对有效.
| 归档时间: |
|
| 查看次数: |
2135 次 |
| 最近记录: |