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.
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.