CarrierWave S3文件检索问题 - 未定义的方法`body'

时间:2013-03-06 05:47:16

标签: ruby-on-rails amazon-s3 carrierwave fog

这让我疯了。我使用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,我可以清楚地看到带有键等的亚马逊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!'

1 个答案:

答案 0 :(得分:4)

我认为这些界限没有意义:

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

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

如果我理解正确,您只需要让用户下载存储在S3中的文件。

你可以通过以下几种方式做到这一点。

最简单的方法是拨打@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 here的更多信息。