Tutorial on how to use Active Storage on Rails 5.2

Facebook
Twitter
LinkedIn

Active storage

Active Storage. This tutorial includes the actual code you can use to try out this feature.

Active Storage is a built-in gem included on Rails 5.2 that handles file uploads to storage services from Amazon, Google, and Microsoft. Saving to local disk is also possible for development and test environments.

This gem replaces Paperclip, Carrierwave, Dragonfly.

We’ll begin by creating a new application.

# install the rails 5.2 beta gem 
# gem install rails -v 5.2.0.beta2

rails new storageapp

Migration

A migration is also created automatically for new applications. If you want to copy the migrations manually, run

bin/rails active_storage:install:migrations
bin/rails db:migrate

This migration adds two tables – active_storage_blobs and active_storage_attachments. These are for the 2 models Blob and Attachment. Blob stores metadata like filename, content-type, byte size and checksum. The actual file is stored in the storage service or disk depending on your settings.

A Blob can be attached to one or more Active Record objects through the Attachment join model.

Active Record Model

Let’s say you want to attach one or multiple images to a Comment. First, we have to create the Comment model. We’ll use the generator to create the resource.

rails g resource comment content:text

One Attachment

You don’t need to use the Blob and Attachment directly. To attach one image to a Comment, use has_one_attached

class Comment < ApplicationRecord
  has_one_attached :image
end

You don’t have to create an Image model. Active Storage uses the Blob and Attachment under the hood to give us comment.image.

Let’s take a look at the controller and views.

class CommentController < ApplicationController
  def new
    comment = Comment.new
  end

  def create
    comment = Comment.create! params.require(:comment).permit(:content)
    comment.image.attach(params[:comment][:image])
    redirect_to comment    
  end

  def show
    comment = Comment.find(paramd[:id])
  end
end
# new.html.erb
<%= form_with model: @comment, local: true  do |form| %>
  <%= form.text_area :content %><br><br>
  <%= form.file_field :image, %><br>
  <%= form.submit %>
<% end %>
# show.html.erb
<%= image_tag @comment.image %>

This is typical code for creating an object. The Active Storage part is comment.image.attach(params[:comment][:images]) on the create action which attaches the file from the image file field to the comment object.

You might also like:   Rails encrypted credentials on 6.2

To display the image, we pass @comment.image to image_tag.

Many Attachments

We only need to modify a few things from the code above to use multiple attachments.

  • has_many_attached instead of has_one_attached
  • comment.images instead of comment.image
  • multiple: true on file_field to allow selection of multiple files
class Comment < ApplicationRecord
  has_many_attached :image
end
class CommentController < ApplicationController
  def new
    comment = Comment.new
  end

  def create
    comment = Comment.create! params.require(:comment).permit(:content)
    comment.images.attach(params[:comment][:images])
    redirect_to comment    
  end

  def show
    comment = Comment.find(paramd[:id])
  end
end
# new.html.erb
<%= form_with model: @comment, local: true  do |form| %>
  <%= form.text_area :content %><br><br>
  <%= form.file_field :images, multiple: true %><br>
  <%= form.submit %>
<% end %>
# show.html.erb
<% @comment.images.each do |image| %>
  <%= image_tag image %> <br />
<% end %>

Configuration

Active Storage is enabled by default when you create a new Rails application. config/active_storage.yml is created and config.active_storage.service is set to :local on both development.rb and production.rb.

local is set to use Disk and the storage directory is used.

local:
  service: Disk
  root: <%= Rails.root.join('storage') %>

To change this, you can specify config.active_storage.service to :amazon, :google, or :microsoft and set the appropriate values on config/storage.yml.

For Amazon S3, you can pass access_key_id, secret_access_key, region, and bucket. For Google Cloud Storage, you can pass project, keyfile, and bucket. For Microsoft Azure Storage, you can pass path, storage_account_name, storage_access_key, and container.

See the generated storage.yml for examples. The credentials should be added using bin/rails credentials:edit. Read about encrypted credentials on Rails 5.2 in our blog post.

You also need to add the necessary gem on the Gemfile for your chosen service. This can be aws-sdk-s3, google-cloud-storage, or azure-storage.

Conclusion

Active Storage makes it easy to handle file uploads to the storage services. We only talked about the basics here. In a future post, we’ll talk about advanced features like direct uploads and variants.

Want more posts like this?

What you should do now:

Facebook
Twitter
LinkedIn

Easy Application Deployment to AWS

Focus on development, not on managing infrastructure

Deploying, running and managing your Ruby on Rails app is taking away precious resources? Engine Yard takes the operational overhead out of the equation, so you can keep innovating.

  • Fully-managed Ruby DevOps
  • Easy to use, Git Push deployment
  • Auto scaling, boost performance
  • Private, fully-configured Kubernetes cluster
  • Linear pricing that scales, no surprises
  • Decades of Ruby and AWS experience

14 day trial. No credit card required.

Sign Up for Engine Yard

14 day trial. No credit card required.

Book a Demo