- Install Active Storage
- Usage
Install Active Storage
Only for Rails version 5.2 and up (Rails 5.2.X & Rails 6.X.X).
- Install
1rails active_storage:install
- 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 < ApplicationRecord23 has_one_attached :document4end
- Many attachments
1class User < ApplicationRecord23 has_many_attached :documents4end
Controller
- One attachment
1class UsersController < ApplicationController2 # your controller methods (index, show ...).3 private45 # Only allow a list of trusted parameters through.6 def user_params7 params.require(:yser).permit(:first_name, :last_name, :document)8 end9end
- Many attachments
1class UsersController < ApplicationController2 # your controller methods (index, show ...).3 private45 # Only allow a list of trusted parameters through.6 def user_params7 params.require(:user).permit(:first_name, :last_name, documents: [])8 end9end
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 :
- Add
gem 'image_processing', '~> 1.2'
to your Gemfile. - Install MiniMagick for image variants.
- To generate previews of PDFs, install Poppler.
- 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 < ApplicationRecord2 has_one_attached :avatar3 has_many_attached :photos45 validates :avatar, presence: true, blob: { content_type: :image } # supported options: :image, :audio, :video, :text6 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 < ApplicationRecord3 has_one_attached :image4end56# ...you can join against :image_attachment to select posts having attached images:7Post.joins(:image_attachment).where('published_at >= ?', Time.now)