uploading a file to Rails JSON API server with Paperclip and Multipart request

paperclip, ruby-on-rails, ruby-on-rails-3

Solution

The pure json way to do this is to not pass content-type multipart-form and pass the file as a base64 encoded string in the json.

I figured this out thanks this post: http://www.rqna.net/qna/xyxun-paperclip-throws-nohandlererror-with-base64-photo.html

Here's an example of the json:

"{\"account\":{\"first_name\":\"John\",\"last_name\":\"Smith\",\"email\":\"john@test.com\",\"password\":\"testtest\",\"avatar\":{\"data\":\"INSERT BASE64 ENCODED STRING OF FILE HERE\",\"filename\":\"avatar.jpg\",\"content_type\":\"image/jpg\"}}}"

Then in the controller process the incoming avatar like this before saving the model.

def process_avatar
  if params[:account] && params[:account][:avatar]
    data = StringIO.new(Base64.decode64(params[:account][:avatar][:data]))
    data.class.class_eval { attr_accessor :original_filename, :content_type }
    data.original_filename = params[:account][:avatar][:filename]
    data.content_type = params[:account][:avatar][:content_type]
    params[:account][:avatar] = data
  end
end

Problem

I want to upload a file from an Android client to a Rails JSON API server. I'm sending a Multipart/form request from the Android client which looks like that: ``` Content-Type: multipart/form-data; boundary=d99ArGa2SaAsrXaGL_AdkNlmGn2wuflo5 Host: 10.0.2.2:3000 Connection: Keep-Alive User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4) --d99ArGa2SaAsrXaGL_AdkNlmGn2wuflo5 Content-Disposition: form-data; name="POSTDATA" Content-Type: application/json; charset=UTF-8 Content-Transfer-Encoding: 8bit {"tags":["test"],"location_id":1,"post":{"content":"test"}} --d99ArGa2SaAsrXaGL_AdkNlmGn2wuflo5 Content-Disposition: form-data; name="IMAGEDATA"; filename="testimage.jpg" Content-Type: image/jpeg Content-Transfer-Encoding: binary <BINARY DATA? --d99ArGa2SaAsrXaGL_AdkNlmGn2wuflo5-- ``` in the rails controller i'm creating the new post with this code: ``` @parsed_json = JSON(params[:POSTDATA]) @post = @current_user.posts.new(@parsed_json["post"]) ``` how do I make Paperclip save the attachment from the multipart form ? I can do it with something like this: ``` if params.has_key?(:IMAGEDATA) photo = params[:IMAGEDATA] photo.rewind @filename = "/tmp/tempfile" File.open(@filename, "wb") do |file| file.write(photo.read) end @post.photo = File.open(@filename) end ``` but it doesn't look like the best solution, also, the filename that is being passed in ther multipart request is not used.

Original source

Related problems