ActiveStorage does so many things out of the box. It handles file uploads, storage, and processing. It also provides a preview of the files. These are known as file representations.
You can call representation on an attachment to display an image variant, or a preview of a video or PDF. If a file can be represented then #representable?
will return true. This is because files such as Word or Excel documents cannot be represented.
Internally, #representation
checks if a file is an image, and if it is, returns a “variant”. If it is a PDF or a video, it creates a “preview”, which is a PNG image of the first page of the PDF or the first frame of the video. If a file can be previewed, #previewable?
will return true.
These representations can either be created on the fly or pre-processed. Pre-processing is done by a background job, ActiveStorage::TransformJob which is run when the file is attached or updated.
Let’s use an example Book
model with attributes name
and cover
to understand this Rails update better.
Before
Now when an image is uploaded, the ActiveStorage::TransformJob is run and the image is pre-processed. A variant is created and stored. When the image is requested, the variant is returned.
However when a PDF or a video is uploaded, the ActiveStorage::TransformJob throws an ActiveStorage::InvariableError
exception.
A quick Google search says that the exception is raised when ActiveStorage::Blob#variant
is called on a blob that isn’t variable.
ActiveStorage::TransformJob
looks like this:
Since PDFs and videos are not images, variants do not exist. Instead, they first need to be converted into an image before image transformations can be applied. This is why the exception is raised.
After
With this Rails update, ActiveStorage::TransformJob now pre-processes PDFs and videos. This PR requests representations
of the blob, instead of variants
. Once an image equivalent of the PDF or video is created, the image transformations are then applied.
Now when a PDF or a video is uploaded, previews can be pre-processed in the background, instead of on the fly. This is a huge performance improvement.