HTML Upload to Amazon S3 with Ruby on Rails

This Blog Post will demonstrate how to build a HTML file upload for images with Ruby on Rails and store the images on Amazon S3 Cloud Storage. I assume that you are familiar with Ruby on Rails and RubyGems.

For the connection to Amazons S3 Storage System we will use the gem “aws-s3”. To use this you have to add this line to your Gemfile:

gem 'aws-s3', '0.6.2', :require => 'aws/s3'

After you added the line to your Gemfile, execute:

bundle

to load the gem. To use aws-s3 is pretty easy. Just add this lines to your “application.rb” file:

AWS::S3::Base.establish_connection!(
      :access_key_id     => 'your_access_key_id',
      :secret_access_key => 'your_secret_access_key'
    )

Just customize the above lines with your access_key_id and your secret_access_key from your S3 Account. Everytime then you are starting your Ruby App AWS will establish a connection to your S3 storage.

OK. Let’s start with the HTML upload form. Here it is:

 <%= form_for @image, :html => {:multipart => true, :accept => "image/gif,image/png,image/jpg"} do |f| %>

   <div>
     <label>Image</label>
   </div>
   <div style="width: 400px;" >
     <%= file_field 'upload', 'datafile'  %>
   </div>

 <div>
   <%= f.submit "Upload image", :class => "button" %>
 </div>

<% end  %>

And the corresponding Ruby Controller looks like this:

class ImagesController < ApplicationController

@@BUCKET = "my_image_bucket"

def create
  fileUp = params[:upload]
  orig_filename =  fileUp['datafile'].original_filename
  filename = sanitize_filename(orig_filename)
  AWS::S3::S3Object.store(filename, fileUp['datafile'].read, @@BUCKET, :access => :public_read)
  url = AWS::S3::S3Object.url_for(filename, @@BUCKET, :authenticated => false)
  @image = Image.new(params[:image])
  @image.user = current_user
  @image.filename = filename
  @image.url = url;
  if @image.save
    flash[:success] = "Image saved! "
    render '/home'
  else
    render '/users/new_image'
  end
end

def destroy
  AWS::S3::S3Object.find(@image.filename, @@BUCKET).delete
  @image.destroy
  render '/home'
end

private 
  
    def sanitize_filename(file_name)
      just_filename = File.basename(file_name)
      just_filename.sub(/[^\w\.\-]/,'_')
    end

end

That’s it. Just cusotmezice the “@@BUCKET” with your Amazon Bucket name.

11 thoughts on “HTML Upload to Amazon S3 with Ruby on Rails

  1. Hi, i want to do something like that. But, i got user controller from devise, and im a little confused cause i dont know if i need a diferent model like.. AvatarController and make relations with UserController. Can you help me please?

  2. Hi; I want to just upload an excel file .xlsx formate. having no model. Simply want to upload this file on amazon-s3, can u guide me. plz

    1. :upload}, :html => {:multipart => true, :accept => “image/gif,image/png,image/jpg”}) do %> Select an Excel File :

      Image

      “button” %>

      Is my view code. I want to change this for file .xlsx formate.

      1. Hi Suny. What exactly is the problem? The code above doesn’t require an model. With the example code I posted above you can upload everything to Amazon S3. Doesn’t matter if it is an Excel file or not.

    1. An update is basically a destroy and a new upload. I avoid S3 code in the Model. I like to centralize code for external services. In my current applications I have a s3 class, which handels all operations with the S3 service.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s