gpt4 book ai didi

ruby-on-rails - Rails - Paper_Clip - 支持多文件上传

转载 作者:行者123 更新时间:2023-12-04 17:40:55 25 4
gpt4 key购买 nike

我在 Rails 3 应用程序上安装了 paper_clip,并且可以上传文件 - 哇,既有趣又简单!

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

我找不到任何教程或 gem 来支持这个开箱即用的。震惊我知道...

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

谢谢

最佳答案

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

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

在 View 中:

<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 主体是原始文件数据,而 header 和文件名在 URL 字符串中传递(这是通过 javascript 异步上传文件的唯一方法)。

这就是它变得复杂的地方,因为 Paperclip 不知道如何处理这些原始请求,您必须捕获它们并将它们转换回标准文件(最好在它们到达您的 Rails 应用程序之前),以便 Paperclip 可以发挥作用。这是通过一些机架中间件完成的,它创建了一个新的临时文件(记住: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'

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

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

免责声明

这是为具有单个、已知且受信任的后端用户的项目实现的。几乎可以肯定,它对高流量 Heroku 应用程序有一些严重的性能影响,我还没有对其安全性进行火力测试。也就是说,它绝对有效。

关于ruby-on-rails - Rails - Paper_Clip - 支持多文件上传,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4001376/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com