如何使用paperclip gem将图像上传到S3

时间:2012-03-29 20:44:50

标签: ruby-on-rails ruby ruby-on-rails-3 paperclip

对于我的生活,我无法理解基本的paperclip example是如何运作的。控制器中只包含一行,那就是

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

我根本不明白将图像上传到s3需要的全部内容。我已经改变了这个例子,因为我想使用jquery file uploader而不是默认的rails形式帮助器,所以我正处于将图像发布到我的控制器的位置,但我无法想象我应该如何从params中取出图像并将其指定为附件。这是我看到的日志:

Parameters: {"files"=>[#<ActionDispatch::Http::UploadedFile:0x132263b98 @tempfile=#<File:/var/folders/5d/6r3qnvmx0754lr5t13_y1vd80000gn/T/RackMultipart20120329-71039-1b1ewde-0>, @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');
    }
});`

有什么帮助我知道如何从上面给出的POSTed参数中剥离文件数据并将其传递给paperclip。我确定我必须为附件属性赋值File.open(...),但我不知道我的文件源是什么。

我花了很多时间试图解决这个问题,我似乎无法得到它。我已经尝试直接上传到s3,但事件链非常令人困惑,所以我想首先完成这个简单的传递示例。非常感谢您给予的任何帮助!

3 个答案:

答案 0 :(得分:4)

如果您可以显示正在使用的确切代码,则需要更多部分,这将有所帮助。

Paperclip可以使用以下方式发布到S3:

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

当您的控制器创建用户模型时,它将发送所有参数。这称为“质量分配”(请务必阅读有关attr_accessible的内容)。

当您的模型收到参数时,它会使用Paperclip AWS处理器上传它。

您需要AWS gem,S3上的有效存储桶和配置文件。

试试此博客文章,如果有帮助,请告知我们:

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

更新2013-04-03:请参阅下面的Chloe评论 - 您可能需要一个额外的参数,博客文章可能已过时。

答案 1 :(得分: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或您使用的任何内容作为发布表单的网址。

答案 2 :(得分:0)

这一位:

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

是包含在表单中发布的文件内容的部分(我认为)。

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

将[:params]传递给User.create方法允许帮助程序获取文件内容,对它们进行任何处理(例如,根据提供给帮助程序的属性调整大小等),然后按下图像到您的存储(例如S3或其他 - S3凭证传递给帮助者)。

希望这能解释'它是如何做到的?'问题

重新jQuery位...不确定代码应该在那里,但为什么不使用Rails表单:remote =&gt;是的,并在jquery中处理响应?