• About
  • Portfolio
  • Blog
  • Contact
Menu

Sebastian Dobrincu

Co-Founder of Revocalize AI. Tech entrepreneur, investor and artist.
  • About
  • Portfolio
  • Blog
  • Contact

How to upload images to Rails API using S3

May 17, 2015

The main reason I'm writing this blog post now is the struggle I've been through, when getting my Rails API to work with S3. The idea is to receive an image (through the API), in Base64 format, convert it to an image and store it locally (temporary) and upload it to S3. Sounds pretty easy, huh?

To start off, we'll add a few gems to our Gemfile:


gem 'carrierwave' 
gem 'carrierwave-base64' 
gem 'fog'
gem 'figaro'
gem 'unf'

Once you configure CarrierWave and CarrierWave-Base64, as well as fog, the next step is to process the received image and upload it to S3. Add the following methods in your controller:

def split_base64(uri_str)
		  if uri_str.match(%r{^data:(.*?);(.*?),(.*)$})
		    uri = Hash.new
		    uri[:type] = $1 # "image/gif"
		    uri[:encoder] = $2 # "base64"
		    uri[:data] = $3 # data string
		    uri[:extension] = $1.split('/')[1] # "gif"
		    return uri
		  else
		    return nil
		  end
end

def convert_data_uri_to_upload(obj_hash)
		  if obj_hash[:image_url].try(:match, %r{^data:(.*?);(.*?),(.*)$})
		    image_data = split_base64(obj_hash[:image_url])
		    image_data_string = image_data[:data]
		    image_data_binary = Base64.decode64(image_data_string)

		    temp_img_file = Tempfile.new("")
		    temp_img_file.binmode
		    temp_img_file << image_data_binary
		    temp_img_file.rewind

		    img_params = {:filename => "image.#{image_data[:extension]}", :type => image_data[:type], :tempfile => temp_img_file}
		    uploaded_file = ActionDispatch::Http::UploadedFile.new(img_params)

		    obj_hash[:image] = uploaded_file
		    obj_hash.delete(:image_url)
		  end
	return obj_hash    
end

Request example: 

{
 "user":{
    	 "name": "John Doe",
     	 "image_url": "data:image/gif;base64,R0lGODlhAQABAJEAAAAAAP////8AAP///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="
 		}   
}

The image_url parameter should contain the Base64-encoded image, in the format above. 

Next, in your controller's create method: 

def create
		@user = User.new(convert_data_uri_to_upload(user_params))

		if @user.save
			render status: 200, json: {
				message: "Successfully added user with ID: " + @user.id.to_s,
				image_url: @user.image_url
			}
		else
			render status: 422, json:{
				errors: @user.errors
			}.to_json
		end
end

Lastly, in Fog.rb:

CarrierWave.configure do |config|
	
  config.fog_credentials = {
    :provider               => "AWS",
    :region                 => ENV['AWS_REGION'],
    :aws_access_key_id      => ENV['AWS_ACCESS_KEY_ID'],
    :aws_secret_access_key  => ENV['AWS_SECRET_ACCESS_KEY']
  }

  if Rails.env.production?  
  	config.root = Rails.root.join('tmp')
  	config.cache_dir = "#{Rails.root}/tmp/uploads"
  end

  config.fog_directory  = ENV['AWS_BUCKET']
  config.fog_public     = false
end

Make sure you set the correct AWS Keys, Region and Permissions (I got stuck on that for a long time). 

If everything went perfect, you should see something similar: 


{
	"message": "Successfully added user with ID: 1",
	"image_url": "https://long-ass-link-to-image"
}

This entire process could be pretty catchy, so pay attention to every little detail as it could make a significant difference. If you have any questions, please don't hesitate to contact me or leave a comment in the section below. I'll be more than happy to help you!

In Web Development Tags rails, api, carrierwave, fog, base64, image
← How to Update your CocoaPods Library Version5 Reasons Why You Should Choose Realm Over CoreData/SQLite →

Fresh Tweets

  • Sebastian Dobrincu
    RT @sama: ‘show up and do stuff, and then do more of what works’ is underrated advice
    Feb 19, 2023, 5:44 AM
  • Sebastian Dobrincu
    Probably the best breakdown of happiness I’ve ever heard. Solid stuff @PeterAttiaMD @arthurbrooks https://t.co/xTkWegJcwZ
    Oct 10, 2022, 5:55 PM

Featured
cocoapods.png
May 28, 2016
How to Update your CocoaPods Library Version
May 28, 2016
Read More →
May 28, 2016
How to upload images to Rails API using S3
May 17, 2015
How to upload images to Rails API using S3
May 17, 2015
Read More →
May 17, 2015