使用Carrierwave将原始文件上传到Rails

12

我的客户想要从Blackberry和Android手机上传图片。他们不想使用a)表单参数或b)多部分消息来发布。他们希望只将文件数据通过POST请求发送到URL。

像这样的操作可以在curl中完成: curl -d @google.png http://server/postcards/1/photo.json -X POST

我想要将上传的照片放入明信片模型的photo属性中,并保存到正确的目录中。

在控制器中,我正在尝试类似以下代码,但是图片在目录中损坏了。我现在手动将文件重命名为“png”:

def PostcardsController < ApplicationController
...
# Other RESTful methods
...
def photo
  @postcard = Postcard.find(params[:id])
  @postcard.photo = request.body
  @postcard.save
end

这个模型:

class Postcard < ActiveRecord::Base
  mount_uploader :photo, PhotoUploader
end
1个回答

18

这是可行的,但您仍需要让客户端发送原始文件名(如果对类型进行任何验证,则还需要发送内容类型)。

def photo
  tempfile = Tempfile.new("photoupload")
  tempfile.binmode
  tempfile << request.body.read
  tempfile.rewind

  photo_params = params.slice(:filename, :type, :head).merge(:tempfile => tempfile)
  photo = ActionDispatch::Http::UploadedFile.new(photo_params)

  @postcard = Postcard.find(params[:id])
  @postcard.photo = photo

  respond_to do |format|
    if @postcard.save
      format.json { head :ok }
    else
      format.json { render :json => @postcard.errors, :status => :unprocessable_entity }
    end
  end
end

现在,您可以使用以下方法设置照片:

curl http://server/postcards/1/photo.json?filename=foo.png --data-binary @foo.png

而要指定内容类型,请使用&type=image/png


1
基本上这正是我所需要的。小细节:新创建的照片(UploadedFile类)需要将“original_filename”设置为某些内容。即使是虚拟数据,Carrierwave也希望有一些东西存在。我的主要问题似乎是我的curl命令,因为我没有正确地发送数据。 - jevy
有人问我,对于curl命令,我使用了这个:curl --form "image[file=@realimage.png;]" http://server/images.json - jevy

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