使用CarrierWave上传RESTful文件 [英] RESTful file uploads with CarrierWave

查看:162
本文介绍了使用CarrierWave上传RESTful文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图建立一个API后端文件上传。我希望能够上传具有该文件的Base64编码字符串的POST请求的文件。服务器应解码字符串,并使用CarrierWave保存文件。这是我到目前为止:

photo.rb:

 类Photo 
包含Mongoid :: Document
包含Mongoid :: Timestamps
mount_uploader:image_file,ImageUploader
end


image_uploader.rb:

  class ImageUploader< CarrierWave :: Uploader :: Base 
storage:file

def store_dir
uploads /#{model.class.to_s.underscore} /#{mounted_as} /#{model .id}
end
end

Rails控制台:
(summary)

  ruby​​-1.8.7-p334:001> img = File.open(../ image.png){| i | i.read} 
=> \377 JFIF\000\001\002\001\000H\000H\000\000\377 Photoshop3.0\0008BIM\003 ...
ruby​​-1.8.7-p334:003> encoded_img = Base64.encode64 img
=> 3af8A \\\
mLpplt5U8q + a7G2 ...
ruby​​-1.8.7-p334:005> p = Photo.new
=>#< Photo_id:4e21b9a31d41c817b9000001,created_at:nil,updated_at:nil,_type:nil,user_id:nil,image_file_filename:nil>
ruby​​-1.8.7-p334 :006> p.user_id = 1
=> 1
ruby​​-1.8.7-p334:007> p.image_file = Base64.decode64 encoded_img
\255 = \254\2007u\226\230-zhwT\253%\036ʉs\232IsM\215˿6\247\ 256 \177 ...
ruby​​-1.8.7-p334:008> p.save
=> true
ruby​​-1.8.7-p334:009> p。 image_file.url
=> nil

full

这个问题似乎与将Base64解码的字符串转换为文件的过程有关。CarrierWave似乎期望File对象,而是给它一个String。那么如何将该字符串转换为File对象。我希望这种转换不会将任何内容保存到文件系统中,只需创建该对象,然后让CarrierWave完成剩下的工作。

> CarrierWave也接受一个StringIO,但是它需要一个 original_filename 方法,因为它需要它来计算文件名并进行扩展检查。如何在Rails 2和3之间进行更改,这里有两种方法:
$ b $ Rails 2

$ $ $ $ $ $ io = StringIO.new(Base64.decode64(encoded_img))
io.original_filename =foobar.png

p.image_file = io
p .save

在Rails 3中,您需要创建一个新类,然后手动添加 original_filename 返回

  class FilelessIO< StringIO 
attr_accessor:original_filename
end
$ b $ i = FilelessIO.new(Base64.decode64(encoded_img))
io.original_filename =foobar.png

p.image_file = io
p.save


I'm trying to build an API backend for file uploads. I want to be able to upload files with a POST request that has a Base64-encoded string of the file. The server should decode the string, and save the file using CarrierWave. Here's what I have so far:

photo.rb:

class Photo
  include Mongoid::Document
  include Mongoid::Timestamps
  mount_uploader :image_file, ImageUploader
end

image_uploader.rb:

class ImageUploader < CarrierWave::Uploader::Base
  storage :file

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end
end

Rails console: (summary)

ruby-1.8.7-p334 :001 > img = File.open("../image.png") {|i| i.read}
 => "\377���JFIF\000\001\002\001\000H\000H\000\000\377�Photoshop 3.0\0008BIM\003...
ruby-1.8.7-p334 :003 >   encoded_img = Base64.encode64 img
=> 3af8A\nmLpplt5U8q+a7G2...
ruby-1.8.7-p334 :005 >   p = Photo.new
 => #<Photo _id: 4e21b9a31d41c817b9000001, created_at: nil, updated_at: nil, _type: nil, user_id: nil, image_file_filename: nil> 
ruby-1.8.7-p334 :006 > p.user_id = 1
 => 1 
ruby-1.8.7-p334 :007 > p.image_file = Base64.decode64 encoded_img
\255��=\254\200�7u\226���\230�-zh�wT\253%����\036ʉs\232Is�M\215��˿6\247\256\177...
ruby-1.8.7-p334 :008 > p.save
 => true 
ruby-1.8.7-p334 :009 > p.image_file.url
 => nil 

full

The problem appears to be related to the process of converting a Base64-decoded string to a file. CarrierWave seems to expect a File object, and instead I'm giving it a String. So how do I convert that String to a File object. I'd like this conversion not to save anything to the file system, simply create the object and let CarrierWave do the rest.

解决方案

CarrierWave also accepts a StringIO, but it expects a original_filename method, since it needs it for figuring out the file name and doing the extension check. How you do it changed between Rails 2 and 3, here's both methods:

Rails 2

io = StringIO.new(Base64.decode64(encoded_img))
io.original_filename = "foobar.png"

p.image_file = io
p.save

In Rails 3, you need to make a new class and then manually add original_filename back

class FilelessIO < StringIO
    attr_accessor :original_filename
end

io = FilelessIO.new(Base64.decode64(encoded_img))
io.original_filename = "foobar.png"

p.image_file = io
p.save

这篇关于使用CarrierWave上传RESTful文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆