Deep Dive: Installing and Configuring Carrierwave for Image Uploads in Rails 5
In this initial deep dive we're going to walk through how to install and configure the Carrierwave library in order to enable the ability to upload files in a Rails application. We're also going to install dot-env, Carrierwave AWS, and additional libraries that are needed for the full feature.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

Great job going through that section, the site is looking so much better. In this deep dive we're actually going to continue working on the application. If you notice, all of our images are hard coded, we're simply calling them from the asset pipeline. I want to specifically walk through how we can create image uploader that allows us to upload images that we can use for our portfolio items.

In these next set of guides we are going to integrate the ability to upload images We are going to utilize a number of libraries in order to make that happen. We are going to integrate

  • dotenv this allows us to securely manage our credentials
  • carrierwave-aws
  • mini_magick is a requirement in order to use a number of the methods provided by carrierwave
  • we are going to be utilizing AWS

You can go sign up for a free AWS account. If you do not want to do that, I will give you an option where you can upload images straight into your application. One thing to know is if you do that second option you won't be able to use heroku to deploy to the web. Heroku doesn't allow for you to upload images into your application.

Open sublime text and open the gemfile. Paste in carrierwave, mini_magick, carrierwave-aws and dotenv-rails.

Now run bundle install. And now bring in all the dependencies and they are now live in the app.

Let's take a look at the carrierwave documentation, click on homepage. Scroll down, it's going to all kinds of information about carrierwave, but all I'm really concerned about is the installation process. We want to create an uploader.rb. switch to the terminal and paste in rails generate uploader Portfolio and this is going to create a file called portfolio_uploader.rb. Update the file to this:

class PortfolioUploader < CarrierWave::Uploader::Base

  storage :file

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def extension_whitelist
    %w(jpg jpeg git png)
  end
end

Go to our portfolio.rb file which is our portfolio model file and we have to set up our mapping between what we have in our uploader and what we have in the database. If you open your schema file you know that we have in the portfolios a main image and the thumb image. We're going to use these to be able to have our uploader. The syntax for adding this is going to be

mount_uploader :thumb_image, PortfolioUploader
mount_uploader :main_image, PortfolioUploader

Now we can customize our _form.html.erb form, which is something that we have not done yet. Let's take a look to make sure the app is still working, which it looks like it is still working. Add this to the _form.html.erb file

<div class="form-group">
  <%= f.file_field :main_image %>
</div>

<div class="form-group">
  <%= f.file_field :thumb_image %>
</div>

Let's check our portfolios_controller.rb to make sure that we have these in our strong params, and we do not. We need to add these because they're going to be passed through. update the portfolio params to this:

def portfolio_params
  params.require(:portfolio).permit(:title, :subtitle, :body, :main_image, :thumb_image, technologies_attributes: [:name])
end

Hit refresh, on localhost:3000/portfolios/new, you should see these items. We're going to spruce these up shortly.

I downloaded a few images, but you can use anything that you want. Add some content and save, everything's still working.

We have a few bugs but bugs are fixable. You may see that all of our placeholder images are gone, that's actually a good thing because that means that carrierwave is working.

The other issue is this image is really big and bulky and crossing over. Open up our show.html.erb and let's fix this. I think the easiest way to manage this is going to add 100% at the very end.

<%= image_tag @portfolio_item.main_image, width: '100%' %>

If I come back here and hit refresh you can see that that fixes that.

I'm not a huge fan of how this is butting up against the top of this. I don't know if we fixed this in our form, but I think it would be worth it to create a new class for a portfolio container. We can use the container across the board for all of our portfolio pages.

<div class="container portfolio-container">

Open up the portfolio.scss file, all the way down you can see we have a portfolio form. Update the form to:

.portfolio-container {
  padding-top: 30px;
}

This is going to look a lot better, it's going to give us a little bit of room here and that's what we want. You'll notice is now our form isn't going to be working. Update new.html.erb and edit.html.erb to reflect the changes

<div class="container portfolio-container">

Hit refresh, everything is working and it looks a lot better.

Before I end this guide, I'm going to open up sublime so that you can see exactly where did that image go. That's a very important thing when it comes to understanding the way rails works. We haven't connected it to the outside world yet so need to find it in our app.

Go to the application/public/uploads. Click on this, you're going to see one called portfolio, inside there is main and thumb image. How in the world did it know how to do all of this? It even named these accurately. The secret is actually in the uploader file, if you remember this store_dir right here, this creates a dynamic path.

I'm going to show you in the next few guides how we can create something and store these files on the remote server and use something that's dedicated purely to file hosting.

  • git status
  • git add .
  • git commit -m "Implemented initial file uploading system via carrierwave for portfolio items:
  • git push origin image-management

We now are ready to move on and start connecting our uploader with an outside server.

Resources