Integrating CarrierWave in my Rails Application

Saman Batool
4 min readNov 6, 2020

This week I decided to backtrack from front-end development for a bit to brush up my Ruby on Rails skills (mainly to test if I may have forgotten anything). Thus, I began an Instagram clone application that includes all CRUD fundamentals. Not to my surprise(well, maybe kind of) I sailed through implementing CRUD (create, read, update, delete) functionality on my app. Once I was done, I was looking through it to see what new features I could add (apart from styling) that were both new to me — so an excuse to learn — and can make the user experience for my application smoother than it was. Enter the CarrierWave gem.

Firstly, if you’re building a web application, you definitely will want to enable image uploading. Image uploading is an important feature in modern-day applications, and images have been known to be useful in search engine optimization.

CarrierWave is a ruby gem that enables image uploading in your application. CarrierWave provides a simple and extremely flexible way to upload files from Ruby applications (just make sure you have Rails on your machine to follow along). To be sure, open up your terminal and enter the command below:

rails -v

That will show you the version of Rails you have installed. For this tutorial I will be using version 6.0.3.4, which you can install like so:

gem install rails 6.0.3.4

Great! Now let’s look at the basic steps you’d need to integrate this gem on to your application (considering you’ve already set up your rails app and MVC using the correct rails commands).

Setting Up CarrierWave

You need to create an initializer for CarrierWave, which will be used for loading CarrierWave after loading ActiveRecord.

Navigate to config > initializers in your project directory and create a file: carrier_wave.rb. Paste the code below into it.

*config/initializers/carrier_wave.rb*require 'carrierwave/orm/activerecord'

From your terminal, generate an uploader:

rails generate uploader Image

This will create a new directory called uploaders in the app folder and a file inside called image_uploader.rb. The content of the file should look like this:

*app/uploaders/image_uploader.rb*# encoding: utf-8class ImageUploader < CarrierWave::Uploader::Base# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process :scale => [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process :resize_to_fit => [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
# def extension_white_list
# %w(jpg jpeg gif png)
# end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end

You can edit it to fit what you want. Let me take you through it.

First, uncomment the MiniMagick line.

...
include CarrierWave::MiniMagick
...

You need this to generate different versions of an image. If you want to generate a thumbnail version of images uploaded, there is already a code form included in the image_uploader file for you. Uncomment the version code block as shown below:

...
version :thumb do
process :resize_to_fill => [50, 50]
end
...

You can also add different versions using the same format.

For the purpose of this blog, we will be saving to file and not fog. Fog is the Ruby cloud service library. I will show you how to put it into use in another part of this series. So leave your storage option as it is.

P.S. For security purposes, certain files might pose a threat if allowed to be uploaded to the wrong location. CarrierWave allows you to specify a white-list of allowed extensions. You should see a method that looks like what I have below, so uncomment it.

...
def extension_white_list
%w(jpg jpeg gif png)
end
...

Now you can mount your uploader. Navigate to your model and paste the code below.

*app/model/image.rb*
mount_uploader :image, ImageUploader

Now, on your views, update your form to follow your controller method.

Open your terminal and start your rails server: rails s.

You should now be able to upload images on your server site.

Validating Image Size

There are a couple of ways to do this. I’ll show you an easy and quick method. Open up your image model and paste in the code below:

*app/model/image.rb
validates_processing_of :image
validate :image_size_validation
private
def image_size_validation
errors[:image] << "should be less than 500KB" if image.size >
0.5.megabytes

This will help ensure that no image greater than 500KB gets uploaded to your Rails application. Start your rails server and check out what you have.

Now you know how to enable image uploading in your Rails application. You have also learned how to validate the format and size. I hope this was helpful in scaling your rails application a tiny notch higher.

Happy coding!

Resources:

https://github.com/carrierwaveuploader/carrierwave

--

--

Saman Batool

Software engineer navigating through problems in Rails and React. I like sharing my thinking processes, solutions and project learnings. I’m based in LI, NY.