How to save a raw_data photo using paperclip

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

Solution

The problem with my previous solution was that the temp file was already closed and therefore could not be used by Paperclip anymore. The solution below works for me. It's IMO the cleanest way and (as per documentation) ensures your tempfiles are deleted after use.

Add the following method to your `User` model:

def set_picture(data)
  temp_file = Tempfile.new(['temp', '.jpg'], :encoding => 'ascii-8bit')

  begin
    temp_file.write(data)
    self.picture = temp_file # assumes has_attached_file :picture
  ensure
    temp_file.close
    temp_file.unlink
  end
end

Controller:

current_user.set_picture(request.raw_post)
current_user.save

Don't forget to add `require 'tempfile'` at the top of your `User` model file.

Problem

I'm using jpegcam to allow a user to take a webcam photo to set as their profile photo. This library ends up posting the raw data to the sever which I get in my rails controller like so: ``` def ajax_photo_upload # Rails.logger.info request.raw_post @user = User.find(current_user.id) @user.picture = File.new(request.raw_post) ``` This does not work and paperclip/rails fails when you try to save request.raw_post. ``` Errno::ENOENT (No such file or directory - ????JFIF??? ``` I've seen solutions that make a temporary file but I'd be curious to know if there is a way to get Paperclip to automatically save the request.raw_post w/o having to make a tempfile. Any elegant ideas or solutions out there? UGLY SOLUTION (Requires a temp file) ``` class ApiV1::UsersController < ApiV1::APIController def create File.open(upload_path, 'w:ASCII-8BIT') do |f| f.write request.raw_post end current_user.photo = File.open(upload_path) end private def upload_path # is used in upload and create file_name = 'temp.jpg' File.join(::Rails.root.to_s, 'public', 'temp', file_name) end end ``` This is ugly as it requires a temporary file to be saved on the server. Tips on how to make this happen w/o the temporary file needing to be saved? Can StringIO be used?

Original source