File uploads in Rails 5.2 with ActiveStorage

File uploads in Rails 5.2 with ActiveStorage

The forthcoming Rails 5.2 release will ship with ActiveStorage, a simple module for handling file uploads either to your own host or to third-party services like Amazon S3 and Google Cloud Storage. If you have worked with Rails, you are likely familiar with gems like CarrierWave and Paperclip. ActiveStorage achieves a similar but more limited end as these libraries.

When writing in the past about ActiveJob, a job queue interface introduced in Rails 4.2, the framework’s author/maintainer David Heinemeier Hansson explained that it is central to the philosophy of Rails that any function that your web application will almost certainly end up incorporating should ship stock with the framework. In the case of ActiveJob, it was recognized that nearly every web application will need a job queue. ActiveStorage is presumably now a consequence of the recognition that nearly every web application will incorporate file upload and storage features to some degree.

At the moment, ActiveStorage’s feature-set is very limited compared to incumbent file upload gems (like CarrierWave and Paperclip). For use-cases where you will need to perform image resizing and/or generate multiple image version (i.e. “thumbnail”, “preview size”, “full-size”) I still recommend CarrierWave. It is a well-thought-out library that aligns strongly with Rails’ conventions and has broad capabilities and flexibility.

Integrating ActiveStorage

The first step to integrating ActiveStorage is to add the gem to your project’s Gemfile:

You’ll then have to add a require 'active_storage' under require 'rails/all' in your project’s application.rb file.

Next, you’ll need to run rails activestorage:install. This is a simple install task included in the library that creates a couple of directories and schema additions upon which the gem relies.

You should see some output like this:

You’ll need to quickly add a config line to your project’s development.rb initializer:

(I’m not sure why this isn’t an assumed development environment default by the gem).

You may need to go into config/storage_services.yml and comment out the amazon, google and mirror storage service blocks, because they attempt to lookup keyfiles and secrets in your project that will not be present.

Next run migrations with rails db:migrate or rake db:migrate.

If you are curious about the schema that ActiveStorage generates, here is the migration:

You can see that there is an active_storage_blobs table, which essentially stores data and metadata about the stored file (including it’s key/path, name and size), and a active_storage_attachments table, which is a polymorphic join table for any of your application record types and the items in the blobs schema. I was personally intrigued to see Global Id string used for the polymorphic association on records. Apparently this has been supported in ActiveRecord for a while but this was the first use I’d seen.

We can now add attachments to our models. Taking the canonical example of a User with avatar, we can use the has_one_attached macro:

The library also provides a has_many_attached macro:

We can make a simple edit form for our User record and add a file field for the ActiveStorage-backed avatar attribute:

This form looks as follows (with some very minimal styling):

User form

ActiveStorage usage within controllers is still a little clumsy as attachment must happen via the attach method versus via direct attribute assignment. I am guessing that this is something that will get ironed out in a near-future release of the gem but meanwhile you must procedurally attach file uploads:

This is all that is required to work with ActiveStorage in its present state. I am incredibly excited to see how this project evolves, and for the Ruby on Rails framework to finally have first-class support for file attachment and management.

Nicholas

Hi! I'm Nicholas and I like building stuff. I'm software development consultant in New York, where I work with startups big and small. I am also a sometime theatre and film nerd. You can reach me by email at nicholas@zaillian.com (public key here if you want to encrypt your message). I keep a personal homepage at nicholas.zaillian.com and accept consulting engagements through my company Written Software.

1 Comment

Tom

about 4 weeks ago

I haven't found a working tutorial yet for getting ActiveStorage to work with Rails 5.1.4!

Reply

Leave a Comment

Please be polite. We appreciate that.
Your email address will not be published and required fields are marked