Naoufal The Tech LeadNavigate back to the homepage

A Ruby On Rails Active Storage Cheatsheet

Naoufal El hassnaoui
June 7th, 2020 · 1 min read

Install Active Storage

Only for Rails version 5.2 and up (Rails 5.2.X & Rails 6.X.X).

  1. Install
1rails active_storage:install
  1. Run migration
1rails db:migrate

Usage

We will use User model with attachment(s) name document(s), this document can be an image or PDF or video or any other type.

Model

  • One attachment
1class User < ApplicationRecord
2
3 has_one_attached :document
4end
  • Many attachments
1class User < ApplicationRecord
2
3 has_many_attached :documents
4end

Controller

  • One attachment
1class UsersController < ApplicationController
2 # your controller methods (index, show ...).
3 private
4
5 # Only allow a list of trusted parameters through.
6 def user_params
7 params.require(:yser).permit(:first_name, :last_name, :document)
8 end
9end
  • Many attachments
1class UsersController < ApplicationController
2 # your controller methods (index, show ...).
3 private
4
5 # Only allow a list of trusted parameters through.
6 def user_params
7 params.require(:user).permit(:first_name, :last_name, documents: [])
8 end
9end

Views (in ERB)

Form filed:

  • One attachment
1<%= form.file_field :document %>
  • Many attachments
1<%= form.file_field :documents, multiple: true %>

Display Image and its variants or Preview (PDF or Video)

Install this libraries first

First to generate variants and previews of PDFs and videos, you will need to :

  1. Add gem 'image_processing', '~> 1.2' to your Gemfile.
  2. Install MiniMagick for image variants.
  3. To generate previews of PDFs, install Poppler.
  4. To generate previews of Videos, install FFmpeg.

Display an image (when document is an image)

To check if there is an image attached before displaying it use:

1if user.documents.attached?
  • One attachment
1<% if user.document.attached? %>
2 <%= image_tag user.document %>
3<% end %>
  • Many attachments

At least one document is attached

1<% if user.documents.attached? %>
2 <% user.documents.each do |document| %>
3 <%= image_tag document %>
4 <% end %>
5<% end %>

Generate a variant of an image with variant

Don’t forget user.document should be an image in this case.

1<%= image_tag user.document.variant(resize_to_limit: [75, 75]).processed %>

.processed method will store the variant for performance reasons.

For more variant transformations check image_processing docs.

Generate a preview with preview

For PDFs or videos.

1<% if user.document.previewable? %>
2 <%= image_tag(user.document.preview(resize: '200x200') %>
3<% end %>

.previewable? method will check if you can create a preview of the document attached.

Don’t know the type of document? Use representation

1<% if user.document.representable? %>
2 <%= image_tag(user.document.representation(resize: '200x200') %>
3<% end %>

.representable? method will check if you can create a preview or a variant of the document attached.

Content type and size

Document attachment content type:

1user.document.content_type

Video attachment file size:

1user.video.byte_size

Attach a local file

In tests for example we want to be able to save/attach local files in Active Storage.

1user.picture.attach(io: File.open('/path/to/file'), filename: 'my_picture.png')

Validation with activestorage-validator gem

To install activestorage-validator gem add in your application’s Gemfile:

1gem 'activestorage-validator'

To use this gem, in your model add:

1class User < ApplicationRecord
2 has_one_attached :avatar
3 has_many_attached :photos
4
5 validates :avatar, presence: true, blob: { content_type: :image } # supported options: :image, :audio, :video, :text
6 validates :photos, presence: true, blob: { content_type: ['image/png', 'image/jpg', 'image/jpeg'], size_range: 1..5.megabytes }
7 # validates :photos, presence: true, blob: { content_type: %r{^image/}, size_range: 1..5.megabytes }
8end

Select all records with an attachment

From the comment in this issue in Rails repository in Github.

1# Assuming a model defined like so:
2class Post < ApplicationRecord
3 has_one_attached :image
4end
5
6# ...you can join against :image_attachment to select posts having attached images:
7Post.joins(:image_attachment).where('published_at >= ?', Time.now)

More articles from Naoufal The Tech Lead

Deno 1.0 What ? NodeJS is dead ? are you serious ?

Two years ago the creator of NodeJS Ryan Dahl announced Deno a secure runtime for JavaScript and TypeScript, in this talk where he talked…

June 7th, 2020 · 1 min read

Here is how to setup a free personal blog using Gatsby, Github, Narative and Netlify

How I managed to lunch this blog with 0$ / DH and here is how you can do it too!

June 6th, 2020 · 2 min read
© 2020 Naoufal The Tech Lead
Link to $https://twitter.com/Naoufal_ELHLink to $https://www.linkedin.com/in/naoufalelh/Link to $https://dev.to/naoufalelh