我正在寻找在Heroku上的Rails应用程序中上传文件的最佳方法。 设置:Rails 3,Carrierwave,Heroku,Mongoid
问题:偶尔,当用户上传不同大小的文件时,图像会保存到数据库中,但在Amazon S3上无法以任何形式提供。这导致图像显示为前端的缺失图像占位符。
可能的原因: 图像已上传但处理过于耗时且请求因Heroku的30秒请求时间限制而超时,或者图像尺寸太大,并且在尝试上传时,请求因H12错误而超时。
解决方案:实施carrierwave-direct并将处理移至后台
阻断剂: CarrierWaveDirect不是CarrierWave的替代品。实际上,它在上传图像的过程中引入了一些重大变化,特别是在db记录持久性的同时不上传图像。此外,它不适用于我现有的目录结构,因此将现有文件移动到新结构似乎过于艰巨。 CarrierWaveBackgrounder与嵌入式文档不兼容。
问题:我该怎么做?示例代码,如果需要,但试图考虑更多,而不仅仅是编码。
答案 0 :(得分:6)
如果您需要处理单个文件,请查看此Railscast,其中包含CarrierWaveDirect并深入上传到S3。结合carrierwave-mongoid gem,如果你想要去那条路线,你应该能够运行单个文件上传。
老实说,我只是去上传多个文件并完成它。在第二部分中,他展示了使用标准Carrierwave和jQuery File Upload而不是CarrierWaveDirect的多文件上传设置。我倾向于同意这个决定。我无法让它正常工作,很可能是因为直接POST到S3所需的所有黑魔法。
Ryan的设置起初看起来很吓人,但它非常简单,而且在source code的剧集中他包含了一个帮助类,它可以处理S3所需的所有数据。
基本工作流程如下:
1)文件通过jQuery插件从浏览器直接上传到S3上的临时存储桶或文件夹。
2)带有临时上传URL的AJAX POST请求转到应用程序,告诉它在数据库中保留并启动工作进程。
3)工作进程下载临时文件,通过CarrierWave设置运行,并将完成的版本存储在正确的位置。
我认为他使用sidekiq作为后台工作,但我使用IronWorker进行了类似的设置,并且效果很好。一旦你有jQuery的东西和CarrierWave设置,你可以真正使用你想要的任何工作。
此外,在评论中我解释了如何处理从临时桶中删除原始上传文件作为工作的一部分,以保持整洁。有关如何直接发布到S3的详细信息,请参阅here。即使你有帮助类,也要明白这一点。