Thursday, April 26, 2007

File upload in Flex + Ruby on Rails

Flex provides an API to upload and download a file. It uses the flash.net.FileReference class. Find the below code

Actionscript 3.0:

Call the "uploadFiles()" method to start uploading a file. Change the URLString variable to point to your controlle

// ActionScript file
import flash.net.FileReference;
import flash.net.URLRequestHeader;

private var uploadFileRefList:FileReference = new FileReference();
private var uploadURLReq:URLRequest;
private var URLString:String="upload/attachment";

private function uploadFiles():void
{
uploadFileRefList.addEventListener(Event.SELECT, uploadSelectHandler);
try {
var success:Boolean = uploadFileRefList.browse();
} catch (error:Error) {
trace("Unable to browse for files. " + error);
}
}
private function doUpload(file:FileReference):void
{
uploadURLReq = new URLRequest(URLString);
file.addEventListener(Event.COMPLETE, uploadCompleteHandler);
file.addEventListener(IOErrorEvent.IO_ERROR, uploadIoErrorHandler);
file.addEventListener(ProgressEvent.PROGRESS, uploadProgressHandler);
try
{
file.upload(uploadURLReq);
} catch (error:Error) {
trace("Unable to upload file. " + error);
}
}
private function uploadSelectHandler(event:Event):void
{
doUpload(uploadFileRefList);
}
private function uploadProgressHandler (event:ProgressEvent):void
{
upload_btn.enabled=false;
trace(Math.floor((event.bytesLoaded/event.bytesTotal)*100) + "% complete");
}
private function uploadIoErrorHandler (event:Event):void
{
trace("Upload failed: " + event);
}
private function uploadCompleteHandler (event:Event):void
{
upload_btn.enabled=true;
trace("Upload successfull: ");
}

Ruby on Rails:

Create a controller "upload" and place the below code
   def attachment
render(:xml => "") if saveFileAttachment(params[:Filedata],params[:Filename].to_s)
end

Then create a helper method "saveFileAttachment"

def saveFileAttachment(pFile,pFileName)
vFilePath = "public/"+pFileName
return false unless File.open(vFilePath, "wb") { |vBuffer| vBuffer.write(pFile.read) }
return true
end