Tutorial on how to use Active Storage on Rails 5.2

  

Active storage.jpg

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.

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 our blog post about encrypted credentials on Rails 5.2 here.

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.

Free Ebook: PaaS Is Dead

Platform as a Service (PaaS) is experiencing a digital transformation, and despite what some may argue, it’s far from dead. Learn why PaaS continues to prove it has a promising future for DevOps.

PaaS Is Dead

Related posts

Ruby on Rails vs PHP

May 16, 2018

There’s more than one way to build a web application. No matter what type of application you are

Read More

What to Look for When Considering Application Hosting

May 8, 2018

Cloud computing has made hosting business-critical applications easier and less expensive.

Read More

5 Commercial Use Cases Continue to Prove the Value of Ruby on Rails

April 11, 2018

Ruby on Rails continues to gain popularity as an effective platform for developing web and

Read More

Christopher Rigor

 
Christopher Rigor is a Senior Technical Evangelist at Engine Yard. He’s a long time Rails user, system administrator, and recently became a contributor of RailsInstaller. Previously, he was the DevOps Support Manager for Asia-Pacific at Engine Yard.
Find me on:

Comments

Subscribe Here!