Processing images with CarrierWave

Share this article

CarrierWave is a gem for managing uploaded files in a Rails application, in this tutorial we will go through the process of uploading and processing images.

Now let’s say we want to have an application where users can upload images and display them in a gallery.

Getting started

he first thing we need to do is create a new rails project in which we will be adding image uploading and processing functionality, so go ahead and fire up a terminal window and execute the following command:

$> rails new your_proyect_name

If you already have a created project you can skip this step.

Go into the project’s directory and open it up in your favorite text editor and open the Gemfile, go to the bottom of the file and add the carrierwave gem there.

gem 'carrierwave'

After you’ve added the gem to your Gemfile go back to your terminal window and execute the ‘bundle’ command to install the gem.

The scaffold

Now lets create a scaffold resource to add carrierwave’s functionality, in your terminal window run the following command:

$> rails g scaffold your_scaffold title:string description:text image:string

This command will create the necesary files and folders for us to work with. Once we have our scaffold resource it’s time to test it out in our browser, in the terminal window run the following command.

$> rails s

ait for it to give you the final prompt, open up your browser and visit: localhost:3000 If you did not get any errors its time to run our migrations to create the necesary tables in our database, so back in your terminal window run the following:

$> rake db:migrate

The Uploader

Once our database is migrated we need to create our uploader with the following command.

$> rails g uploader your_uploader

This command will create a folder under your app directory called ‘uploaders’ and inside that folder you will find your created uploader class, open up the uploader in your text editor and you will see that this file has already some code in it and comes with pretty good documentation on how you can customize it, but for the purpose of this tutorial we can leave it as is. Now open up your Image model to mount the uploader:

[gist id=’3025218′]

Add this line under your attr_accessible call, and that should be all you need to add to your model, so the completed code for the model should look like this.

[gist id=’3025223′]

The Views

Go into your views folder and open up your ‘new.html.erb’ file created by the scaffold, in here edit the following line and enable the form to upload files.

[gist id=’3025443′]

So the edited line should look like this:

[gist id=’3025447′]

Also we need to edit the input for ‘image’ in order to let us choose a file from our local machine and upload it, so in the same view edit this line:

[gist id=’3025450′]

Replace the ‘textfield’ with ‘filefield’, save the file and head over to your ‘show.html.erb’

Displaying the image

Once you’re in the show template locate the following line:

<%= @image.image %>

And replace it with this:

<%= @image.image_url %>

One little gotcha is that when no image is saved to the database this will return nil, so you might want to convert the 'image_url' to a string with a call to the 'to_s' method.

The Thumb

Once this is all done it’s time give it a try, so fire up your rails server and head on over to ‘localhost:3000/images/new’ in here upload an image and verify everything is working as expected.

Now that you’ve upload an image you’ll notice that in the index template it still shows the plain URL for the image so it is time to make ourselves a thumb version of the image.

Installing ImageMagick

Now if you’re on a Mac this will make your life a lot easier, if you have ‘homebrew’ installed just run the following command:

$> brew install imagemagick

If you're following this tutorial on other than Mac you can find the documentation on ImageMagick here:ImageMagick

Go grab a cup of coffee or a beer if you will and wait for it to finish.

Once we have ImageMagick installed head on over to your uploader file and uncomment the following line:

include CarrierWave::MiniMagick

This will give us an ImageMagick wrapper for ruby, i recommend mini-magick since it gives us access to a set of helper methods to manipulate images very easily, so after you uncomment the line add this piece of code to your uploader file.

[gist id=’3025458′]

This will process the uploaded image and resize it to the dimensions specified.

Displaying the thumb

Open up ‘index.html.erb’ and locate this line:

<%= image.image %>

And add the url method passing the version you want to display, in this case our thumb, like so:

<%= image_tag image.image_url(:thumb) %>

Final Step

Open your gem file one more time and add the mini_magick gem under the carrierwave gem:

gem "mini_magic"

Return to your terminal window and run the bundle command to install the gem, after the installation has finished fire up the server, visit ‘localhost:3000/images/new’ and upload an image, if everything went well you should see your uploaded image in the show template and the thumb version of the image in the index template, hope you enjoyed it.

Further Reading

If you feel that carrierwave is the right choise for you, you can visit their wiki page on github to get more information on how te set up a more complex uploader.

Frequently Asked Questions (FAQs) about Processing Images with CarrierWave

How do I install CarrierWave in my Rails application?

To install CarrierWave in your Rails application, you need to add the gem to your Gemfile. Open your Gemfile and add the following line: gem 'carrierwave', '~> 2.0'. Then, run the bundle install command in your terminal to install the gem. After the gem is installed, you can generate an uploader by running rails generate uploader Image. This will create a file in your app/uploaders directory where you can specify how you want your images processed.

How do I use CarrierWave to upload multiple images?

CarrierWave allows you to upload multiple images by using the mount_uploaders method in your model. First, you need to change the column type in your database to JSON or array. Then, in your model, you can use mount_uploaders :images, ImageUploader. This will allow you to upload multiple images at once.

How can I resize images with CarrierWave?

To resize images with CarrierWave, you can use the resize_to_fit or resize_to_fill method in your uploader. These methods take two arguments: width and height. For example, resize_to_fit 800, 800 will resize the image to fit within an 800×800 pixel area.

How do I handle image versions with CarrierWave?

CarrierWave allows you to create different versions of your uploaded images. In your uploader, you can use the version method to define a new version. For example, version :thumb do process resize_to_fit: [50, 50] end will create a thumbnail version of your image.

Can I store my images in the cloud with CarrierWave?

Yes, CarrierWave supports various cloud storage services like Amazon S3, Google Cloud Storage, and more. You can specify your storage service in the CarrierWave.configure block in your initializer.

How do I validate file size with CarrierWave?

CarrierWave provides a size_range method that you can use to validate the size of the uploaded file. For example, size_range 0..1.megabytes will only allow files that are less than or equal to 1 megabyte.

Can I process images asynchronously with CarrierWave?

Yes, CarrierWave supports asynchronous processing through the use of background jobs. You can use gems like Sidekiq or Resque to handle background processing.

How do I handle errors with CarrierWave?

CarrierWave provides various methods to handle errors. For example, you can use the download! method to download a file and raise an error if the download fails.

Can I use CarrierWave with ActiveStorage?

While both CarrierWave and ActiveStorage are used for file uploads in Rails, they are not designed to be used together. You should choose one or the other based on your specific needs.

How do I test my CarrierWave uploaders?

You can test your CarrierWave uploaders using RSpec. CarrierWave provides a be_format matcher that you can use to test the format of your uploaded files. For example, expect(uploader).to be_format('jpg') will test if the uploaded file is a JPEG.

Benjamin Iandavid RodriguezBenjamin Iandavid Rodriguez
View Author

Im a RoR developer located in Mexico(Mexicali to be exact), I started developing in rails back in 2007 and loved it, I also have experience in social networks and front end development using javaScript libraries. I love the rails way, Starcraft 2, my beautiful wife and my android powered son.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week