I’m not sure how common of use case this is, but I recently had to work with an image being raw posted to my app via a Flash application and had a need to push it through attachment_fu for thumbnailing and to integrate with my models. After reading up on request.raw_post in the Rails API, I came across a blog post that gave me most of the solution I needed. Basically, we need to spoof all of the attributes that attachment_fu looks for when it parses the uploaded data: the content type, the original filename, and the data itself. My modified version of LocalFile looks like this:

require 'tempfile'
class RawFile
 attr_reader :original_filename
 attr_reader :content_type

 def initialize(filename, content, content_type)
  @content_type = content_type
  @original_filename = filename
  @tempfile = Tempfile.new(@original_filename)
  @tempfile.write(content)
 end

 def path #:nodoc:
  @tempfile.path
 end
 alias local_path path

 def method_missing(method_name, *args, &block) #:nodoc:
  @tempfile.send(method_name, *args, &block)
 end
end

Which borrows heavily from the aforementioned blog post with the exception of getting the content passed directly into the initializer instead of being read from a file and getting the content type directly. Now I was ready to write my controller action to take the raw post data (in this case, raw JPEG data), create a Tempfile using it and subsequently pass that through to attachment_fu as though it were an uploaded form item. Here’s the relevant part of the action:

def create
  image_params = {:user_id => params[:uid], :uploaded_data => RawFile.new(params[:name],request.raw_post,"image/jpeg")}
  @photo = Photo.new(image_params)
end

This simple little bit of code will take a filename parameter passed through along with a raw post of JPEG data and create a new RawFile from it, which can be passed as the uploaded_data attribute of the attachment model. So if you need to integrate attachment_fu or any other Rails upload solution with raw data, this might be a way to do it!

Leave a Reply