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.
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?
What exactly you want to do? Can you please describe your problem?
Usually one Controller should be enough.
Can I be shown how to do this using paperclip?
I don’t know how to do that with paperclip. I never used paperclip.
If you know how to do it with paperclip you are welcome to post link here.
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
: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.
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.
Very helpful info! Any hints on what the update method should look like? Does it make sense to move the s3 stuff into the model? thanks!
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.
there is another way to do to big files? great post!
good information robert ..thanks