Adding Active Storage to your Rails Project

Introduction

Active Storage is a new feature in Rails that lets us upload and store images without having to install any third-party libraries or gems.

It's also great because it lets us put things right into cloud storage services like Amazon S3, Microsoft Azure Storage, and Google Cloud Storage.

You can read up on more of the specifics here. But let's jump into how to set it up and use it!


Setup

Installing Active Storage

Installing Active Storage is really easy. Doesn't matter if you're starting a new Rails project from scratch or trying to add it to an existing project, just install it with this command:

rails active_storage:install

Under the hood, this will generate a migration that adds 2 new database tables to map your assets to your Active Record objects.

AWS Made Easy
AWS Made Easy
How to learn AWS quickly and easily.
AWS Made Easy
LEARN MORE

Setting up cloud storage

Next up, we can configure the cloud storage provider we plan to use.

The configuration is stored in the config/storage.yml file.

Depending on the cloud storage we plan on using, the configuration might look slightly different.

The official Rails documentation might be more helpful for this specific part.


How to use Active Storage

Setup our models

Active Storage works with any model, as it uses a polymorphic association with those 2 database tables we created earlier.

To allow a model to use Active Storage, we just have to declare a field that handles how our images are "attached" to our model.

We have two options here, the first for when we intend for there to be just one image:

has_one_attached :primary_image

And if we want a model to support multiple images we use this variant:

has_many_attached :carousel_images

Together our model would look like this:

# app/models/blog_post.rb

class BlogPost < ApplicationRecord
  has_one_attached :primary_image
  has_many_attached :carousel_images
end

Setup our views

In order to upload images to Active Storage, we can use the file_field input type and pass the same attribute name that our model uses. That means we'll define an input for both our :primary_image and our :carousel_images.

<div class="field">
  <%= form.label :primary_image %>
  <%= form.file_field :primary_image %>
</div>

One difference with our :carousel_images field, is since it uses the has_many_attached attribute and supports multiple images, we also need to add the multiple: true attribute to this input field. This will let us select and upload multiple files at once.

<div class="field">
  <%= form.label :carousel_images %>
  <%= form.file_field :carousel_images, multiple: true %>
</div>

Speed it up with a CDN

Now that our assets are stored in the cloud, our app won't be bogged down trying to serve web requests and images at the same time. That's a nice little performance improvement, but we can take it a step further.

If we add a CDN in front of our cloud storage, we should be able to serve our assets from a closer location to our visitors which should reduce latency and increase response times even more!

For the time being, check out this great post on adding a CDN on top of Active Storage.

I'll cover this topic more in-depth soon too though.

Final Words

Active Storage is in my opinion a very nice addition to Rails and I encourage anyone that still uses Paperclip or other gems to consider switching.

Check out my other post that covers more of how Active Storage works under the hood and a few more reasons why people should use it!

Feel free to reach out to me on Twitter if you have questions or want to dig a little deeper too.

Featured
Level up faster
Hey, I'm Nick Dill.

I help people become better software developers with daily tips, tricks, and advice.
Related Articles
More like this
How to Export to CSV with Ruby on Rails
What is MVC and Why Should I Use It?
Understanding the Ruby on Rails Asset Pipeline