Using Ruby on Rails Active Storage on Digital Ocean
Active Storage is a new feature of Ruby on Rails 5 for handling image and file attachments. It replaces the need for using external image handing gems such as tried and sturdy Paperclip, which is now deprecated, with the maintainer recommending using Active Storage. So there you go, it's time to move on. Active Storage has been well thought through, with a very clean implementation, allowing for much greater on-the-fly flexibility, rather than strict advance determination of image sizes.
In this post, I'll show you how to configure Active Storage, using Digital Ocean (referral link) Spaces as the file store.
Active Storage uses two tables to manage storage:
active_storage_attachments. Once you have upgraded to at least Rails version 5.2, you can run a generator and migrations for these files:
rails active_storage:install rails db:migrate
Defining the storage services you will use is done in
config/storage.yml. Here we have added the definition for
digitalocean and you should notice that the service type is
S3, which conveniently enough is the same as Digital Ocean, so these instructions will work for either service.
First, you will need credentials to use Digital Ocean Spaces, go to API > Spaces Access Key > Generate New Key. With the credentials, we will store them using Rails custom credentials
Once you have the credentials, modify
test: service: Disk root: <%= Rails.root.join("tmp/storage") %> local: service: Disk root: <%= Rails.root.join("storage") %> digitalocean: service: S3 endpoint: <%= Rails.application.credentials.digital_ocean[:endpoint] %> access_key_id: <%= Rails.application.credentials.digital_ocean[:access_key_id] %> secret_access_key: <%= Rails.application.credentials.digital_ocean[:secret_access_key] %> region: <%= Rails.application.credentials.digital_ocean[:region] %> bucket: <%= Rails.application.credentials.digital_ocean[:bucket] %>
Failure to set any of the credentials will tend to yield an error:
Unable to autoload constant ActiveStorage::Blob::Analyzable
Defining which service to use in specific environment files, ie.
config/environments/development.rb, which is this case is to use
config.active_storage.service = :digitalocean
Since we are going to use Digital Ocean, we need to add the AWS gem
gem "aws-sdk-s3", require: false
For attaching files, you have a choice to either attach one (hasone) or many (hasmany) to a model, in this case
class User < ApplicationRecord has_one_attached :avatar end
In the form, you can simply add:
<%= form.file_field :avatar %>
And to see if an image is attached?
In the case of a has_many relationship:
class User < ApplicationRecord has_many_attached :images end
And to add additional images:
To remove all of the attached images:
Additional Image Transformation Setup
To be able to use variants of your original images, you need to add the
image_processing gem to your
Gemfile, which will by default incorporate and use
MiniMagick under the covers, but you can use other processors as well such as
gem 'image_processing', '~> 1.2'
I did my install using the Digital Ocean Ruby on Rails Ubuntu image, which needs ImageMagik, installed with:
sudo apt-get install imagemagick
For handling variants, when the browser requests a variant url, Active Storage will lazily transform the original BLOB into the requested format:
<%= image_tag user.avatar.variant(resize_to_fit: [100, 100]) %>
Carson R Cole