loading...
Cover image for A Ruby On Rails Active Storage Cheatsheet

A Ruby On Rails Active Storage Cheatsheet

naoufalelh profile image Naoufal El hassnaoui Originally published at gist.github.com ・3 min read

Rails Active Storage Cheatsheet

Without an introduction, here is the table of content:


Install Active Storage

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

  1. Install
rails active_storage:install
  1. Run migration
rails 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
class User < ApplicationRecord

  has_one_attached :document
end
  • Many attachments
class User < ApplicationRecord

  has_many_attached :documents
end

Controller

  • One attachment
class UsersController < ApplicationController
  # your controller methods (index, show ...).
  private

  # Only allow a list of trusted parameters through.
  def user_params
    params.require(:yser).permit(:first_name, :last_name, :document)
  end
end
  • Many attachments
class UsersController < ApplicationController
  # your controller methods (index, show ...).
  private

  # Only allow a list of trusted parameters through.
  def user_params
    params.require(:user).permit(:first_name, :last_name, documents: [])
  end
end

Views (in ERB)

Form filed:

  • One attachment
<%= form.file_field :document %>
  • Many attachments
<%= 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:

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

At least one document is attached

<% if user.documents.attached? %>
  <% user.documents.each do |document| %>
    <%= image_tag document %>
  <% end %>
<% end %>

Generate a variant of an image with variant

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

<%= 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.

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

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

Don't know the type of document? Use representation

<% if user.document.representable? %>
  <%= image_tag(user.document.representation(resize: '200x200') %>
<% 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:

user.document.content_type

Video attachment file size:

user.video.byte_size

Attach a local file

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

user.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:

gem 'activestorage-validator'

To use this gem, in your model add:

class User < ApplicationRecord
  has_one_attached :avatar
  has_many_attached :photos

  validates :avatar, presence: true, blob: { content_type: :image } # supported options: :image, :audio, :video, :text
  validates :photos, presence: true, blob: { content_type: ['image/png', 'image/jpg', 'image/jpeg'], size_range: 1..5.megabytes }
  # validates :photos, presence: true, blob: { content_type: %r{^image/}, size_range: 1..5.megabytes }
end

Select all records with an attachment

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

# Assuming a model defined like so:
class Post < ApplicationRecord
  has_one_attached :image
end

# ...you can join against :image_attachment to select posts having attached images:
Post.joins(:image_attachment).where('published_at >= ?', Time.now)

I posted this originally in Github as a Gist: here

Posted on May 26 by:

naoufalelh profile

Naoufal El hassnaoui

@naoufalelh

Tech Lead at Eutech Maroc - eHealth solutions developer - Ruby On Rails | GraphQL | React & RN | Web enthusiast.

Discussion

markdown guide