Articles

Adding File Upload Capability to Your Ruby on Rails Apps

Introduction

Most web applications today need the capability of uploading documents, photos and files of various formats. The active community around Rails has built some great plugins to carry out these operations with substantial ease.

As a use case, we will continue building our employee management system. Here, each employee needs to upload their photo in order to complete their records. They help to upload files on a file system, database or a cloud storage like Amazon S3.

Getting the Prerequisites Right

Install a graphics library that facilitates the recognition of image formats. Imagemagick is the most commonly used graphics library and for our sample we will use that. Download the Windows binary and follow the setup which is pretty straight forward. We will also need to install a Ruby wrapper around Imagemagick in order to make your Rails application understand the Imagemagick libraries.

C:> gem install rmagick

For Linux systems ensure that you compile Imagemagick from source and for Windows you can download the compatible bundle of Imagemagick and Rmagick. Many people run into compatibility issues between these two before getting it right. You can also look at minimagick as an alternative which uses less memory than rmagick.

Installing the RoR Plugin

In order to install the plugin, take the URL of the source repository and run the plugin installation command as in figure 1.

run the plugin installation command
Figure 1

C:> ruby script/plugin install git://github.com/technoweenie/attachment_fu.git

This creates a folder under the vendor/plugins directory and contains all the plugin code.

Get your Upload Box and Button

We will start by creating an upload form. Attachment_fu uses two parts in its form:

<%= f.file_field :uploaded_data %>

This method looks for the appropriate file to be uploaded in the system. Once this is added, we will be able to browse the file system and select the file to be uploaded. Internally it uses file_field helper class.

The second part of the form is as follows:

 

<% form_for(:uploads, :url => upload_path, 
:html => { :multipart => true }) do |f| -%>

The URL directive in this looks for the Restful route of the uploaded file and sends the uploaded file as a Post Form Request. The :multipart => true method generates the form data which needs to sent over the Post.

Hence, the overall form looks like this:

 

  <%= error_messages_for :uploads %>
<% form_for(:uploads, :url => upload_path, 
:html => { :upload => true }) do |f| -%>
<p>
<label for="upload">Please Upload Your Photo:</label>
<%= f.file_field :uploaded_data %>
</p>
<p>
<%= submit_tag 'Create' %>
</p>
<% end -%>

Prepare the Database and Validate the Uploads

We will start by creating a model and will also generate a migration.

 

C:> ruby script/generate model upload

run the plugin installation command
Figure 2

The migration file will have the table definition. We will store all the attribute information regarding the filename in the table.

Here is how we do that in 20091119052703_create_uploads.rb:

 

  class CreateUploads < ActiveRecord::Migration
def self.up
create_table :uploads do |t|
t.column :user_id,  :integer
t.column :content_type, :string
t.column :filename, :string    
t.column :thumbnail, :string 
t.column :size, :integer
t.column :width, :integer
t.column :height, :integer
t.timestamps
end
end
def self.down
drop_table :uploads
end
end

Content type column stores the file mime type and checks if it is an image, document or PDF, filename as it says stores the name of the file. A thumbnail is generated for the file so as to add it to places where need to add the download link to the file. Size, width and height are image specific attributes and pertain to the file type.

The Upload model essentially contains all the attribute definitions and information that needs to be known while an upload is going on.

 

  class Upload < ActiveRecord::Base
has_attachment :content_type => :image, 
:storage => :file_system, 
:max_size => 800.kilobytes,
:resize_to => '200x150>',
:thumbnails => { :thumb => '80x80>' }
validates_as_attachment
end

has_attachment is the magical method, it contains all the information that our attachment_fu requires in order to give a desired result to our image upload. Lets look at some of the terminology associated with it.

 

  • :content_type - It defines weather we are uploading an image, a document, or a video.
  • :min_size and :max_size defines the minimum and maximum limits of the file size.
  • :size overrides the min_size and max_size directives and gives a range of sizes like 200..300.
  • :resize_to gives the size of the resultant image, the size to which the image will resize to once it is uploaded.
  • :thumbnails provides the size of the thumbnails to be generated and displayed as the download file option.
  • :path_prefix allows you to add a custom path on the file system for the storage of the file.
  • :storage puts the storage system to be used like Amazon S3 or a normal file system.
  • :processor defines the image processor like rmagick, minimagick.

Now that we have defined where to upload and what to upload, we will add the control as to how to upload.

The Create Method

Creating the Control
Figure 3

Create the controller with:

 

C:> ruby script/generate controller uploads

And add the generate create method to it.

 

  class UploadsController < ApplicationController
def new
@upload = Upload.new
end
def create
@upload = Upload.new(params[:upload])
if @upload.save
flash[:notice] = 'Your Photo was successfully Uploaded.'
redirect_to upload_url(@upload)     
else
render :action => :new
end
end
end

This method, creates a new record in the database once the upload is done, and on saving it redirects to the page where the uploaded file will be displayed.

Now, we know what we have done. In the front end we will see a thumbnail, the database contains the attributes of the file and we will, in the back end, refer to the absolute path of the file on the file system.

  <h1>Employee Photos</h1>
<% for uploads in @uploads -%>
<%= link_to image_tag(upload.public_filename(:thumb)), upload.public_filename %>
<% end -%>

There are other methods to add file uploads like the Paperclip plugin which again is a very simple way to do it. You can check paper clip out here.

Conclusion

File uploads can be done in Rails using plugins. They provide an easy and straightforward way to add file uploads to your app. In our next articles and will look at various methods of testing our Ruby on Rails app. Stop by next week and check it out.

Original article


Website Design | Website Development | Flash animation | Flex applications | Logo Design | Mobile Applications Development | iPhone | iPad | Google Android

Content Management Systems | E-Commerce | Social Networking | Dating Websites | Membership Websites | Zend Framework | PRADO | Symfony | Wordpress

ASP.NET | PHP | C# | Objective-C | AJAX | Web 2.0 | HTML | CSS | Javascript | MySQL | MSSQL

 


Host unlimited domains + get up to 5 FREE domains with your 1&1 hosting account. Must see monthly hosting specials!


Invite your friends to Stable Flow

Enter up to 3 email addresses of your friends: