如何使用paperclip gem上传图片到S3

3

就算我拼尽全力,也无法理解基本的回形针示例是如何工作的。控制器中只包含了一行代码:

@user = User.create( params[:user] )

我简单地不明白这就足以上传图片到s3了。我已经对示例进行了相当大的更改,因为我想使用jquery文件上传器而不是默认的rails表单助手,所以我现在处于这样一个阶段:一张图片被POST到我的控制器,但我无法弄清楚该如何从参数中获取图片并将其分配为附件。以下是我在日志中看到的内容:
参数: {"files" => [#,@headers =“Content-Disposition:form-data; name = \”files [] \“; filename = \”background.png \“\ r \ nContent-Type:image / png \ r \ n“,@content_type =”image / png“,@original_filename =”background.png“> ],“id” =>“385”}
我的JS非常简单:
 ` $('#fileupload').fileupload({
    dataType: 'json',
    url: '/my_url',
    done: function (e, data) {
        console.log('done');
    }
});`

我需要知道的是如何从上述POST参数中提取文件数据并将其传递给paperclip。我确定我必须为附件属性分配File.open(...)的值,但我不知道我的文件来源在哪里。
我已经花了很多时间来尝试解决这个问题,但似乎无法解决。我尝试直接上传到s3,但事件链非常混乱,因此我想先完成这个简单的通过示例。非常感谢您能提供的任何帮助!
3个回答

4
你需要更多的代码片段,并且如果你能展示你正在使用的确切代码,那将会有所帮助。
Paperclip可以通过以下方式上传到S3:

http://rubydoc.info/gems/paperclip/Paperclip/Storage/S3

当您的控制器创建用户模型时,它会发送所有参数。这被称为“批量赋值”(请务必阅读有关attr_accessible的内容)。
当您的模型接收到参数时,它使用Paperclip AWS处理器进行上传。
您需要AWS gem、S3上的有效bucket和一个配置文件。
尝试这篇博客文章,如果有帮助,请告诉我们:

http://blog.trydionel.com/2009/11/08/using-paperclip-with-amazon-s3/

更新于2013年4月3日:请参考下面Chloe的评论--您可能需要一个额外的参数,而博客文章可能已过时。


我理解到了这一点,但我不明白为什么我们可以期望params包含Paperclip所期望的所有属性。除非表单助手正在处理此事,否则我需要找到一个解决方法,因为我将不使用表单助手。已经在原始帖子中编辑了一些JS代码。谢谢。 - D-Nice
我的建议是让你先按照演示中展示的方式,不使用jQuery使其正常工作。当成功实现后,再加入jQuery。这种方法可以更容易地逐步查看事物的运行情况。 - joelparkerhenderson
博客文章不好。可能已经过时了。按照步骤出现了错误。Paperclip RubyDoc中没有提到的一件事是在has_attached_file中添加:storage => :s3。他们让人觉得:s3_credentials就足够了,但实际上并不是这样。 - Chloe
谢谢Chloe,我会在答案中加上一条注释感谢你!(随意编辑整个答案) - joelparkerhenderson

1
如果你想手动完成它,可以这样做:
# In order to get contents of the POST request with the photo,
# you need to read contents of request
upload = params[:file].is_a(String)
file_name = upload ? params[:file] : params[:file].original_filename
extension = file_name.split('.').last

# We have to create a temp file which is going to be used by Paperclip for
# its upload
tmp_file = "#{Rails.root}/tmp/file.#{extension}"
file_id = 0

# Check if file with the name exists and generate unique path
while File.exists?(tmp_file) do
  tmp_file_path = "#{Rails.root}/tmp/file#{file_id}.#{extension}"
  id += 1
end

# Let's write the file from post request to unique location
File.open(tmp_file_path, 'wb') do |f|
  if upload
    f.write request.body.read
  else
    f.write params[:file].read
  end
end

# Now that file is saved in temp location, we can use Paperclip to mimic one file
# upload
@photo = Photo.new :photo => File.open(tmp_file_path)

# We'll return javascript to say that the file is uploaded and put its thumbnail in
# HTML or whatever else you wanted to do with it
respond_to do |format|
  if @photo.save
    render :text => "Success"
  else
    render :text => @photo.errors
  end
end

你可以重新编写你的create或者任何你用来作为表单POST的URL。


0
这一段代码:
"files"=>[#<ActionDispatch::Http::UploadedFile:0x132263b98 @tempfile=#     <File:/var/folders/5d/6r3qnvmx0754lr5t13_y1vd80000gn/T/RackMultipart20120329-71039-1b1ewde-0>

这是我认为保存在表单中的文件内容的部分。

在Rails中,用户模型将有一个帮助程序:has_attached_file

通过将[:params]传递给User.create方法,该帮助程序可以获取文件内容,在其上执行任何处理(例如根据提供给帮助程序的属性进行调整大小等),然后将图像推送到您的存储(例如S3或其他 - S3凭据传递给帮助程序)。

希望这解释了“它是如何实现的?”的问题

关于jQuery部分...不确定代码应该是什么,但为什么不使用具有:remote => true的Rails表单,并在jquery中处理响应呢?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接