Cloudinary Blog

Ruby on Rails image uploads with CarrierWave and Cloudinary

by Nadav Soferman

When we set to develop Cloudinary’s Rails integration Gem, it was obvious to us that we’ll base it on CarrierWave. Here’s why.

Photos are a major part of your website. Your eCommerce solution will have multiple snapshots uploaded for each product. Your users might want to upload their photo to be used as their personal profile photo. What’s entailed when developing such a photo management pipeline, end-to-end?


  • You’ll need an HTML file upload form.
  • The server will need to manage the reception and processing of the uploaded image files.
  • Uploaded images should be stored on a safe storage with access for multiple application servers.
  • Model entities should keep references to uploaded images.
  • Uploaded images will need to be resized and cropped into different dimensions matching the graphics design of your web site.
  • The server will need to find and deliver the resized images to visitors of your site when displaying a page with the relevant model entity (e.g., display a thumbnail of the profile picture in a user profile page, etc.).
  • Allow overriding uploaded images with new ones when needed.
Cloudinary allows you to overcome this complexity in its entirety, but how does it work?

Over the years, we’ve had the pleasure of using some of RoR’s many excellent file upload solutions: CarrierWave, Paperclip, Dragonfly, attachment_fu and others. All-in-all, CarrierWave often proved a better fit for our needs:

  • Simple Model entity integration. Adding a single string ‘image’ attribute for referencing the uploaded image.
  • "Magic" model methods for uploading and remotely fetching images.
  • HTML file upload integration using a standard file tag and another hidden tag for maintaining the already uploaded "cached" version.
  • Straight-forward interface for creating derived image versions with different dimensions and formats. Image processing tools are nicely hidden behind the scenes.
  • Model methods for getting the public URLs of the images and their resized versions for HTML embedding.
  • Many others - see CarrierWave documentation page.
What we liked most is the fact the CarrierWave is very modular. You can easily switch your storage engine between a local file system, Cloud-based AWS S3, and more. You can switch the image processing module between RMagick, MiniMagick and other tools. You can also use local file system in your dev env and switch to S3 storage in the production system.
 
When we developed Cloudinary and decided to provide a Ruby GEM for simple Rails integration, it was obvious that we’ll want to build on CarrierWave. Our users can still enjoy all benefits of CarrierWave mentioned above, but also enjoy the additional benefits that Cloudinary provides:
  • The storage engine is Cloudinary. All images uploaded through CarrierWave model methods are directly uploaded and stored in the cloud. 
  • All resized versions and image transformations are done in the cloud by Cloudinary: 
    • No need to install any image processing tools or Ruby GEMs. 
    • You can create the resized versions eagerly while uploading or lazily when users accesses the actual images. Save processing time and storage.
    • Change your desired image versions at any time and Cloudinary will just create them on the fly, no need to batch update all your images when the graphics design of your site changes.
  • All public image URLs returned by CarrierWave are Cloudinary URLs. This means they are automatically delivered through a global CDN with smart caching. Seamlessly enhancing the performance of your web application.
Some code samples:

class PictureUploader < CarrierWave::Uploader::Base

  include Cloudinary::CarrierWave
  
  version :standard do
    process :resize_to_fill => [100, 150, :north]
  end
  
  version :thumbnail do
    process :resize_to_fit => [50, 50]
  end     
    
end
class Post < ActiveRecord::Base
  ...
  mount_uploader :picture, PictureUploader
  ...
end
= form_for(:post) do |post_form|
  = post_form.hidden_field(:picture_cache)
  = post_form.file_field(:picture)
= image_tag(post.picture_url, :alt => post.short_name)

= image_tag(post.picture_url(:thumbnail), :width => 50, :height => 50)

We believe that for Ruby on Rails developers, the combination of Cloudinary with its CarrierWave-based gem, delivers a complete image management solution, with excellent model binding.

More details about about our CarrierWave plugin are available in our documentation: http://cloudinary.com/documentation/rails_integration#carrierwave_upload

What do you think about our solution? any suggestions or improvement ideas?

UPDATE: We've published another post about additional advanced image transformations in the cloud with CarrierWave & Cloudinary.

Recent Blog Posts

Dynamic ZIP files generation with a single line of code

As a developer, you want to allow your users to download multiple files in a single click. An easy way to download multiple files and share them is to generate a ZIP file. When images are involved, you may also want to normalize the original images before including them in the ZIP file, by scaling them down to the same maximum resolution or converting them to the same format.

Read more
How mindbodygreen reduce costs & save development time

mindbodygreen is a digital media brand dedicated to health and wellness. The company’s website bring together leaders in the wellness world, best-selling authors, fitness experts, trusted healers, pioneering doctors, top chefs, celebrities and top-tier journalists to provide readers fresh, expert content and tools to help them live healthy, happy lives. The company was founded in 2009 and is headquartered in Brooklyn, N.Y. 
Read more

Why JPEG is like a photocopier

by Jon Sneyers
Why JPEG is like a photocopier (generation loss)

If you make a copy of a copy of a copy, the quality will deteriorate with every ‘generation’. This problem is called ‘generation loss’. It is not difficult to understand why this happens with actual copier machines. Scanning and printing are not perfect, being based on noisy sensors and physical paper and ink, and the resulting noise will tend to accumulate.

Read more
Apply conditions to dynamically manipulate images.

It's great to have the capability to manipulate images on the fly by using dynamic URLs to customize the images to fit the graphic design of your site or mobile application. However, what if you want to manipulate an image depending on a specific image characteristic (like its width or aspect ratio) or its contents (does it contain a face?). What you need is a way to apply a transformation to an image only if a specific condition is met. Take for example a situation where you have allocated space on your page for a user uploaded image with a width and height of 200 pixels. Furthermore, if the image contains a face you would like to zoom in and focus on the face itself, otherwise you would like to fit the entire image into the available space:

Read more
Moviepilot focus on core business and reduce costs
 
Moviepilot Inc. is a media company that hosts a website and social publishing platform designed to bring together movie and TV fans, and help studios trigger, fuel and amplify positive conversations about entertainment topics. The site invites fans to create content, such as writing articles and producing videos, which are then curated on the site and distributed to more than 30 million fans worldwide. The site boasts more than 20 million unique visitors per month, with 87 percent of visitors accessing the site on mobile devices. The company is headquartered in Venice Beach, Calif., and has an office Berlin, Germany, where it was originally founded.
Read more