3

这让我发疯了。我将 CarrierWave 与 Amazon S3 一起使用,我可以安全地将文件上传到存储桶,并且我现在尝试(在不同的请求中)检索文件并将其作为下载文件传送到浏览器。

这些文件可以是任何东西,.zip 文件等。我不使用它来存储图像。

Bucket 是私有的,不是公共的,所以我不能只使用 S3 URL。

这是我的检索代码:

au = @note.attachment
au.retrieve_from_store!(File.basename(@note.attachment.to_s))
au.cache_stored_file!

cache_stored_file 上的代码错误!线。抛出错误:

undefined method `body' for nil:NilClass

我检查了该对象,它对我来说看起来不错,如果我输出 @note.attachment,我可以清楚地看到带有键等的 amazon s3 URL。

我一直在网上,我可以弄清楚。我发现有少数人有同样的问题,他们通过做与我的案例无关的事情来解决这个问题(比如使用一些 imagemagick 方法),同样,这些只是文件。

没有处理或图像工作,我只想将文件作为下载返回给浏览器。

有人可以帮忙吗?

这是我的上传者:

class AttachmentUploader < CarrierWave::Uploader::Base

  storage :fog

  def store_dir
    "#{Rails.env}/#{model.id}"
  end

  def cache_dir
    "#{Rails.root}/tmp/attachments"
  end
end

和痕迹

carrierwave (0.8.0) lib/carrierwave/storage/fog.rb:225:in `read'
carrierwave (0.8.0) lib/carrierwave/uploader/cache.rb:77:in `sanitized_file'
carrierwave (0.8.0) lib/carrierwave/uploader/cache.rb:116:in `cache!'
carrierwave (0.8.0) lib/carrierwave/uploader/cache.rb:73:in `cache_stored_file!'
4

1 回答 1

4

我认为这些行没有意义:

au = @note.attachment
au.retrieve_from_store!(File.basename(@note.attachment.to_s))
au.cache_stored_file!

retrieve_from_store是您通常会在上传器上调用的东西,而不是在附加对象上调用的东西。将附件的基本名称传递给自身的复杂步骤应该会响起警钟。

如果我对您的理解正确,您只是想让用户能够下载您存储在 S3 中的文件。

您可以通过多种方式做到这一点。

最简单的方法是将 URL 调用@note.attachment.url并打印为用户可以单击的链接。

另一种方法是将用户重定向到控制器操作中的 url。

# notes/1/download_attachment   
def download_attachment
  @note = Note.find(params[:id)
  redirect_to @note.attachment.url
end

最后一种方法是充当代理服务器/缓存,从 S3 获取文件并返回。

您可以在控制器中执行以下操作:

file = open(@note.attachment.url)
send_data file

请注意,我没有机会测试最后一个代码片段。

您可以在此处阅读有关send_data 的更多信息。

于 2013-03-06T08:15:15.487 回答